<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta woas_permanent="1" http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script woas_permanent="1" type="text/javascript">
/* <![CDATA[ */

/* DFQRCTsKlU-0000217-START */

var woas = {"version": "0.12.0"};

var __marker = "DFQRCTsKlU-0000217";

woas["config"] = {
"permit_edits":true,
"dblclick_edit":false,
"save_on_quit":false,
"nav_history":false,
"allow_diff":true,
"key_cache":true,
"cumulative_save":false,
"safe_mode":false,
"debug_mode":false,
"main_page":'Main Page',
"wsif_author":'Anonymous',
"wsif_ds":'',
"wsif_ds_multi":false,
"wsif_ds_lock":false,
"auto_save":0,
"new_tables_syntax":true,
"store_mts":false,
"folding_style":0,
"import_settings":107};

var current = 'Main Page';

var backstack = [
];

var page_titles = [
'::Menu',
'Special::Advanced',
'Special::Import',
'Special::About',
'Main Page',
'Special::Search',
'Special::Lock',
'WoaS::Help::Security',
'Special::Options',
'WoaS::Help::Deprecated syntax',
'WoaS::Help::Special::Options',
'Special::Embed',
'WoaS::Plugins',
'WoaS History',
'Special::Export',
'Special::License',
'WoaS::Aliases',
'Special::ExportWSIF',
'WoaS::Help::WSIF',
'Special::ImportWSIF',
'WoaS::Help::Macros',
'WoaS::Help::Index',
'WoaS::Help::Syntax',
'WoaS::Template::Button',
'WoaS::Help::Special::Advanced',
'WoaS::Help::Special::Erase Wiki',
'WoaS::Help::CSS',
'WoaS::Help::Special::Dead Pages',
'WoaS::Help::General usage',
'WoaS::Help::Nowiki text',
'WoaS::Template::Info',
'WoaS::Help::Wiki is read-only',
'WoaS::Help::Create a page',
'WoaS::Help::Delete a page',
'WoaS::Help::Editor',
'WoaS::Help::Edit a page',
'WoaS::Help::Erase all pages',
'WoaS::Help::Edit the menu',
'WoaS::Help::Headers',
'WoaS::Help::Rulers',
'WoaS::Help::Include text file',
'WoaS::Help::Include web page',
'WoaS::Help::Include wiki page',
'WoaS::Help::JavaScript',
'WoaS::Help::Join lines of text',
'WoaS::Help::Namespaces',
'WoaS::Help::Text formatting',
'WoaS::Help::Rename a page',
'WoaS::Help::Page scrolling',
'WoaS::Help::Table of Contents',
'WoaS::Help::Tags',
'WoaS::Help::Publish wiki online',
'WoaS::Help::Run wiki on a webserver',
'WoaS::Help::Requirements',
'WoaS::Help::Lists',
'WoaS::Help::Tables',
'WoaS::Help::Links',
'WoaS::Help::Images',
'WoaS::Help::Import',
'WoaS::Template::Search',
'WoaS::Help::Export',
'WoaS::Template::Example::Transclusion',
'WoaS::Help::Transclusion',
'WoaS::Help::Special::ExportWSIF',
'WoaS::Help::Special::ImportWSIF',
'WoaS::Hotkeys',
'WoaS::CSS::Core',
'WoaS::CSS::Custom',
'WoaS::CSS::Boot',
'WoaS::Help::Hotkeys',
'WoaS::Help::Plugins',
'WoaS::Help::Aliases',
'WoaS::ImportSettings',
'old main menu',
'Boek Trust Soap',
'About WSDL/SOAP',
'PersistentService',
'Test'
];

/* DFQRCTsKlU-0000217-DATA */
var page_attrs = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];

var page_mts = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

var pages = [
'[[Main Page]]\n\
[[Boek Trust Soap]]\n\
[[old main menu]]\n\
[[About WSDL/SOAP]]\n\
[[PersistentService]]\n\
[[Test]]\n\
\n\
[[Include::WoaS::Template::Search]]\n\
\n\
\n\
\n\
',
'== Pages\n\
* [[Locked::]], [[Unlocked::]]: a list of all encrypted/plain pages\n\
* [[Special::All Pages]]: a list of all user created pages in this wiki\n\
* [[Special::Dead Pages]]: a list of nonexistent pages that other pages link to \n\
* [[Special::Delete Page]]: delete specific page\n\
* [[Special::Go to]]: go to specific page\n\
* [[Special::New Page]]: create a new page\n\
* [[Special::Orphaned Pages]]: a list of pages that no other pages link to\n\
* [[Special::Recentchanges]]: view recently modified pages\n\
* [[Special::Search]]: search all wiki pages\n\
* [[Tagged::]], [[Untagged::]]: a list of all tagged/untagged pages\n\
\n\
== Advanced features\n\
* [[Special::Options]]: general WoaS options\n\
* [[WoaS::Aliases]]: view/edit page title aliases\n\
* [[WoaS::CSS::Core]], [[WoaS::CSS::Custom]]: view the core CSS and edit the custom CSS\n\
* [[WoaS::Hotkeys]]: view/edit WoaS access keys and default key bindings\n\
* [[WoaS::Plugins]]: enable/disable and view/edit WoaS JavaScript plugins\n\
\n\
== Maintenance\n\
* [[Special::Import]]: import wiki from an early (or current) version\n\
* [[Special::ImportWSIF]]: import a wiki page (or collection of) in [[WoaS::Help::WSIF|WSIF]] format\n\
* [[Special::Export]]: export wiki into multiple linked static XHTML files\n\
* [[Special::ExportWSIF]]: export wiki into multiple or single [[WoaS::Help::WSIF|WSIF]] files\n\
* [[Special::Erase Wiki]]: delete ALL wiki pages and reset with default data',
'Import a wiki /.html/ source from an early (or current) version:\n\
\n\
File: \x3Cinput id="filename_" type="file" /\x3E&nbsp;\x3Cinput id="btn_import" class="woas_button" type="button" value="Import" onclick="import_wiki()" /\x3E\n\
\n\
== Source\n\
\x3Clabel for="woas_cb_import_config"\x3E\x3Cinput type="checkbox" id="woas_cb_import_config" checked="checked"\x3E&nbsp;Import configuration (except WSIF datasource settings)\x3C/label\x3E\n\
\x3Clabel for="woas_cb_import_content"\x3E\x3Cinput type="checkbox" id="woas_cb_import_content" checked="checked"\x3E&nbsp;Import pages\x3C/label\x3E\n\
\x3Clabel for="woas_cb_import_styles"\x3E\x3Cinput type="checkbox" id="woas_cb_import_styles"\x3E&nbsp;Import CSS\x3C/label\x3E\n\
[[Include::WoaS::ImportSettings]]\n\
\n\
\x3Cscript type="text/javascript"\x3E\n\
woas.ui._import_xhtml_load();\n\
\x3C/script\x3E',
'[[Special::TOC]]\n\
= Welcome to Wiki on a Stick!\n\
Wiki on a Stick (in short *WoaS*) is a [[http://en.wikipedia.org/wiki/Wiki|wiki]] that lives in *one self-modifying XHTML file*. It\'s perfect to be used at home or at office, on your laptop or USB pen drive. It can be used as a personal notepad, calendar, repository for software documentation and for many other purposes; it allows full customization and extension by your own scripts and plugins. It also offers [[WoaS::Help::Security|AES encryption]] of pages.\n\
\n\
== Version\n\
\n\
Current version is *v0.12.0*\n\
Versions 0.9&tilde;0.12.0 by Daniele C. ([[http://sf.net/users/legolas558/|legolas558]])\n\
Original version (v0.01 &tilde; v0.04) by Andr\u00e9 Wagner\n\
\n\
\x3Cbig\x3E[[Special::License|Wiki on a Stick is licensed under the GNU/GPL license]].\x3C/big\x3E\n\
\n\
== Official Website\n\
\n\
\x3Cimg style="display: inline; visibility: visible;" id="img_logo" alt="WoaS Logo" src="%2FAAAAAXNSR0IArs4c6QAAAAJiS0dEAP%2BHj8y%2FAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH2gEcDzUY4t9JowAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAI7SURBVEjHtdVPSFRRFAbw33ujljETWhaGo9YiCGoVuHDTIggE2xRBbgeEoFWQFARBq3ZCELQKgqJtbWtTEAitgqBNCZJFGGb%2B18Hxz20xr3HSmXEU%2Bt7ivnvf%2B757z3feOydSAZNh2QrW0IAm%2Bx2LVMS25e9h0UbFF5u1aI1qCvwMs9ZVRyStK6oq8D3M2xn7HdYSVRAYC3n1ocHRslDi4vCtbjprpspmcTH2BbtBwddQJjATZu0Wi36FvwFZqOk861atbUttvDku1SAHeUsKFb6MueQM8c%2BwUcOuJatVnxYDb8hX3XtFoWZoxZM3LFkpW0wlfmxY29HIvNnQEsV5fQql62IyVqO%2FknPegNtgFfG6wyZ80GtaQRrjcnpdN5eQhvTrNwaG5Tx3S0%2BSH%2BIga9SItA8mZTGs21MZTxKBnMfuJLOsLzLOupL4RJySNeadGyWBT645adAbMO6xnCHvwUNcMmg0cYy4Ubc30vp9NaG7FG1TYueQHve9sAjSBr10xj3QiLhZp1F96PRWJ854ZsIjF8CK07LeYQ4PfJRyCuzTGhEfkJVyAeeMyOKmTy5bkAODbhsw4ZyrGDekz2t3kSnWg5nwWbAXHHcsIm6NDu2J%2FrfMxrRJ7UGgffNvPBQd2TU9UyrzMZyIDu6K3qRja13o0Fw3PaWrrKiWbmbCDwt17d7lSFSlsYyG3zukNKNjS3fa0md%2BhUnzVRPXXqFDVmiZU2HOouV%2Fjn1QRntUV3PdxHRYRUpb5H%2FiD%2FUerIBA%2BEx5AAAAAElFTkSuQmCC" /\x3E [[http://stickwiki.sourceforge.net|WoaS Official Website]]\n\
\n\
== Download\n\
Wiki on a Stick can always be downloaded through the official SF.net WoaS project file download service:\n\
\x3Cbig\x3E[[https://sourceforge.net/projects/stickwiki/files/|Download Wiki on a Stick]]\x3C/big\x3E\n\
\n\
== Get support\n\
\n\
You can use the [[http://woas.iragan.com/|official WoaS forums]] and the [[http://sf.net/projects/stickwiki/|SF.net WoaS project facilities]].\n\
\n\
== Thanks to\n\
This project wouldn\'t be what it is without the help of other people. If you contributed to Wiki on a Stick and your name is not here (or if you do not want it to be listed here), please [[http://sourceforge.net/sendmessage.php?touser=799761|contact the mantainer]].\n\
* *Jeremy Ruston* - the creator of the wonderful [[http://www.tiddlywiki.com/|TiddlyWiki]], who served as inspiration for Wiki on a Stick\n\
* *Philip O\'Donnel* - creator of the table syntax & parsing code\n\
* *Tim Lord*\n\
* *Knut Kohl*\n\
* *Rob Schmersel*\n\
* *Michiel van Everdingen* - [[http://home.versatel.nl/MAvanEverdingen/Code/|original javascript implementation]] of AES encryption\n\
* *Cyril Mazard* - search feature\n\
* *jimmac* - author of [[http://jimmac.musichall.cz/i.php?i=gorilla-stock|the icons set]] which we are currently using in WoaS\n\
* *martinellison* - transclusion patch\n\
* *Nilton Castillo* - bugfixes and enhancements (original pluggable macro syntax)\n\
* *Little Girl* - documentation, overall testing, various improvements\n\
* [[http://weekendtesting.com/archives/833|Europe Weekend Testing]] - which provided a testing session for WoaS\n\
* [[http://testconsultant.blogspot.com/|Jeroen Rosink]] - for testing WoaS releases\n\
\n\
== Important links\n\
* [[http://sf.net/projects/stickwiki/|SourceForge project home page]] - useful for contributing\n\
* [[http://woas.iragan.com/|Official WoaS forums]] - our discussion forums where you can also participate to the decision processes\n\
* [[http://sourceforge.net/tracker/?group_id=155218&atid=794925|SF.net WoaS project bug tracker]] - if you find a bug, post it here\n\
* [[http://sourceforge.net/tracker/?group_id=155218&atid=794928|SF.net WoaS project feature tracker]] - if you have have suggestions for improvements\n\
* [[http://www.iragan.com/woas_irc/|Official WoaS IRC Channel]] - #woas room at FreeNode servers\n\
* [[https://lists.sourceforge.net/lists/listinfo/stickwiki-devel|SF.net WoaS Development mailing list]] - for public discussion',
'= Welcome to the Boek Trust Soap server documentation\n\
\n\
== Read about the [[Boek Trust Soap]] project\n\
\n\
* This is written in [[http://stickwiki.sourceforge.net|Wiki on a Stick]] (in short WoaS) is a wiki that lives in one self-modifying XHTML file. It\'s perfect to be used at home or at office, on your laptop or USB pen drive. It can be used as a personal notepad, calendar, repository for software documentation and for many other purposes; it allows full customization and extension by your own scripts and plugins. It also offers AES encryption of pages.',
'= Search in Wiki\n\
\n\
\x3Cinput id="string_to_search" type="text" onfocus="search_focus(true)" onblur="search_focus(false)" /\x3E&nbsp;\x3Cinput class="woas_button" type="button" value="Search" onclick="ssearch_do_search()" /\x3E&nbsp;\x3Cinput class="woas_button" type="button" value="Clear" onclick="woas.ui.clear_search()" /\x3E\n\
\x3Cdiv id="woas_search_results"\x3E&nbsp;\x3C/div\x3E\n\
\n\
\x3Cscript type="text/javascript" language="javascript"\x3E\n\
woas._search_load();\n\
\x3C/script\x3E',
'== AES encryption\n\
Read more about the [[WoaS::Help::Security|embedded AES encryption]] used in Wiki On a Stick.\n\
\n\
== Password\n\
Enter your password for AES encryption. The more complex your password is, the more difficult it will be to attack the encryption. It is suggested *not* to use passwords whose textbox color is \x3Cspan style="background-color:red"\x3E&nbsp;red&nbsp;\x3C/span\x3E, and to accept passwords only when the textbox color is \x3Cspan style="background-color:lime"\x3E&nbsp;green&nbsp;\x3C/span\x3E. Punctuation and Mixed case characters will exponentially increase the strength of your password.\n\
\x3Cdl\x3E\x3Cdt\x3E\x3Clabel for="pw1"\x3EEnter password:\x3C/label\x3E\x3C/dt\x3E\x3Cdd\x3E\x3Cinput type="password" id="pw1" style="background-color:red" value="" size="50" onfocus="woas.ui.focus_textbox()" onblur="woas.ui.blur_textbox()" onkeyup="pw_quality()" /\x3E&nbsp;\x3Cspan id="txtBits"\x3E&nbsp;\x3C/span\x3E\x3C/dd\x3E\x3Cdt\x3E\x3Clabel for="pw2"\x3ERe-enter password:\x3C/label\x3E\x3C/dt\x3E\x3Cdd\x3E\x3Cinput type="password" id="pw2" value="" size="50" onfocus="woas.ui.focus_textbox()" onblur="woas.ui.blur_textbox()" /\x3E\x3C/dd\x3E\x3C/dl\x3E\x3Cinput id="btn_lock" class="woas_button" type="button" value="" /\x3E\n\
\x3Cscript type="text/javascript"\x3E\n\
	_lock_page();\n\
\x3C/script\x3E',
'== AES encryption\n\
[[http://en.wikipedia.org/wiki/Advanced_Encryption_Standard|AES]] 256-bit high security data encryption standard is supported to protect a single page or groups of them.\n\
\n\
WoaS has two different interfaces for encryption passwords, namely one for encryption (called *Locking*) and one for decryption (called *Unlocking*).\n\
\n\
== Encryption\n\
\n\
An interface for page encryption shows also a colored meter for estimated password quality; encryption password is not stored in your saved files (true AES encryption is used).\n\
\n\
[[Include::WoaS::Template::Info|*If you forget the password there is no way to retrieve it or your data.*]]\n\
\n\
In order to encrypt a page you will have to click on the /lock/ icon in the navigation bar. The page locking interface will have two password boxes (the second for verification); the background color of the first box will hint about password estimated strength.\n\
\n\
Once you\'ve chosen and typed in your password, click the *Lock* button to encrypt the page.\n\
\n\
When encrypting additional pages during a session, you\'ll be offered to use the same password you used to encrypt the first page. Accept by pressing the *OK* button or decline by pressing the *Cancel* button. If you decline, the password interface will open, allowing you to set a new password for the page. There is no limit to how many passwords you can use.\n\
\n\
== Decryption\n\
\n\
Click the *Set password* icon in the navigation bar to set the decryption password used for next page.\n\
\n\
The password for decrypting a page (or pages) is cached so that you only need to enter it once per session. If you close or reload the wiki, you will need to reenter the password to work with the encrypted page(s). To disable the password cache, check the box for *Do not temporarily cache the AES key* in the wiki [[WoaS::Help::Special::Options|Options]]. If you\'ve used more than one password for encrypting your pages, you\'ll need to enter the password to unlock each encrypted page.\n\
\n\
== Security level\n\
Security is never absolute. Data encrypted with these pages might be compromised in a variety of ways, including but not limited to the following:\n\
\n\
* WoaS uses random numbers generated by the browser itself, and they are not secure (user-generated entropy will be used in future versions)\n\
* User-generated passwords are weak by nature (PBKDF2 will be used in future)\n\
* You have not disabled the AES key cache, so when you will enter the password for the first time other users (if not you) will be able to see encrypted pages and could possibly get your key\n\
* Your Web browser and/or JavaScript interpreter may contain bugs or deliberate security violations which report activity on your computer back to some other Internet site\n\
* Some other applet running on another page in your browser, perhaps without you being aware of its existence, is spying on other windows\n\
* Some other "spyware" application running on your computer may have compromised your system\'s security and be snooping on your activity\n\
* The implementation of the encryption may contain a bug which makes its results insecure, Wiki on a Stick is open-source, you can judge for yourself whether the tool merits your confidence.\n\
* Your computer\'s security may have been compromised physically; when\'s the last time you checked that a bug that transmits your keystrokes and/or screen contents to that white van parked down the street wasn\'t lurking inside your computer cabinet?\n\
\n\
Apart from the above, your normal usage of encrypted pages can be considered secure.',
'= Options\n\
\n\
== User Interface\n\
\x3Clabel for="cb_dblclick_edit"\x3E\x3Cinput type="checkbox" id="cb_dblclick_edit" onclick="woas.config.dblclick_edit = d$.checked(\'cb_dblclick_edit\')" /\x3EDouble click to edit pages/menu\x3C/label\x3E\n\
\x3Clabel for="cb_key_cache"\x3E\x3Cinput type="checkbox" id="cb_key_cache" onclick="woas.config.key_cache = !d$.checked(\'cb_key_cache\')" /\x3EDo not temporarily cache the AES key\x3C/label\x3E\n\
\x3Clabel for="cb_rem_history"\x3E\x3Cinput type="checkbox" id="cb_rem_history" onclick="woas.config.nav_history = d$.checked(\'cb_rem_history\')" /\x3ERemember current page and navigation history\x3C/label\x3E\n\
\x3Clabel for="cb_fixed_layout"\x3E\x3Cinput type="checkbox" id="cb_fixed_layout" onclick="_set_layout(d$.checked(\'cb_fixed_layout\'))" /\x3EFixed menu area and navigation bar\x3C/label\x3E\n\
\x3Clabel for="cb_debug_mode"\x3E\x3Cinput type="checkbox" id="cb_debug_mode" onclick="woas.config.debug_mode = d$.checked(\'cb_debug_mode\')" /\x3EEnable debug mode and debug console (*requires WoaS reload*)\x3C/label\x3E\n\
\n\
== Saving\n\
\x3Clabel for="cb_allow_diff"\x3E\x3Cinput type="checkbox" id="cb_allow_diff" onclick="woas.config.allow_diff = d$.checked(\'cb_allow_diff\')" /\x3EMake merge/diff of WoaS XHTML/WSIF datasource easier\x3C/label\x3E\n\
\x3Clabel for="cb_save_on_quit"\x3E\x3Cinput type="checkbox" id="cb_save_on_quit" onclick="woas.config.save_on_quit = d$.checked(\'cb_save_on_quit\')" /\x3EAutomatically save options (if changed) before quitting\x3C/label\x3E\n\
\x3Clabel for="cb_cumulative_save"\x3E\x3Cinput type="checkbox" id="cb_cumulative_save" onclick="woas.config.cumulative_save = d$.checked(\'cb_cumulative_save\')" /\x3EEnable cumulative save (will save to disk only when quitting)\x3C/label\x3E\n\
\x3Clabel for="cb_safe_mode"\x3E\x3Cinput type="checkbox" id="cb_safe_mode" onclick="woas.config.safe_mode = d$.checked(\'cb_safe_mode\')" /\x3EEnable safe mode (embedded &lt;script/&gt; blocks and WoaS::Plugins not executed, *requires WoaS reload*)\x3C/label\x3E\n\
\x3Clabel for="cb_store_mts"\x3E\x3Cinput type="checkbox" id="cb_store_mts" onclick="woas.config.store_mts = d$.checked(\'cb_store_mts\')" /\x3EStore and display last modified timestamp\x3C/label\x3E\n\
\x3Clabel for="cb_new_tables_syntax"\x3E\x3Cinput type="checkbox" id="cb_new_tables_syntax" onclick="woas.config.new_tables_syntax = d$.checked(\'cb_new_tables_syntax\')" /\x3EEnhanced tables syntax\x3C/label\x3E\n\
\n\
== Datasource\n\
\x3Clabel for="cb_wsif_ds_lock"\x3E\x3Cinput type="checkbox" id="cb_wsif_ds_lock" onclick="woas.config.wsif_ds_lock = d$.checked(\'cb_wsif_ds_lock\')" /\x3ELock WSIF datasource when editing\x3C/label\x3E\n\
\x3Clabel for="cb_wsif_ds_multi"\x3E\x3Cinput type="checkbox" id="cb_wsif_ds_multi" onclick="woas.config.wsif_ds_multi = d$.checked(\'cb_wsif_ds_multi\')" /\x3EUse multiple files in WSIF datasource\x3C/label\x3E\n\
/Disabling above option will not remove WSIF files created for each page/\n\
WSIF data source: \x3Cinput id="txt_wsif_ds" type="text" size="60" value="" onchange="woas.config.wsif_ds=this.value" /\x3E\n\
/Relative path to WSIF datasource to use (blank to disable); file will be overwritten./\n\
A file named as above WSIF data source and ending with ".lck" will also be created to manage locking.\n\
\n\
WSIF data author: \x3Cinput id="txt_author" type="text" size="12" value="" onchange="woas.config.wsif_author=this.value" /\x3E\n\
/Used in exported WSIF content or in WSIF datasources./\n\
\n\
\x3Cp\x3E\x3Cinput class="woas_button" type="button" onclick="save_options()" value="Save options" /\x3E\x3C/p\x3E\n\
== Permanent changes\n\
\x3Cp\x3E&nbsp;&nbsp;\x3Cinput class="woas_button" type="button" onclick="ro_woas()" value="Disallow edits" /\x3E\n\
/Caution: to re-enable editing you will have to manually edit WoaS/\x3C/p\x3E\n\
\x3Cscript type="text/javascript"\x3E\n\
d$("cb_allow_diff").checked = bool2chk(woas.config.allow_diff);\n\
d$("cb_rem_history").checked = bool2chk(woas.config.nav_history);\n\
d$("cb_store_mts").checked = bool2chk(woas.config.store_mts);\n\
d$("cb_new_tables_syntax").checked = bool2chk(woas.config.new_tables_syntax);\n\
d$("cb_key_cache").checked = bool2chk(!woas.config.key_cache);\n\
d$("cb_dblclick_edit").checked = bool2chk(woas.config.dblclick_edit);\n\
d$("cb_debug_mode").checked = bool2chk(woas.config.debug_mode);\n\
d$("cb_save_on_quit").checked = bool2chk(woas.config.save_on_quit);\n\
d$("cb_cumulative_save").checked = bool2chk(woas.config.cumulative_save);\n\
d$("cb_safe_mode").checked = bool2chk(woas.config.safe_mode);\n\
d$("cb_wsif_ds_multi").checked = bool2chk(woas.config.wsif_ds_multi);\n\
d$("cb_wsif_ds_lock").checked = bool2chk(woas.config.wsif_ds_lock);\n\
d$("cb_fixed_layout").checked = (d$("woas_wiki_header").style.position == "fixed");\n\
\n\
if (woas.browser.ie6) d$("cb_fixed_layout").disabled = true;\n\
\n\
d$("txt_author").value = woas.config.wsif_author;\n\
d$("txt_wsif_ds").value = woas.config.wsif_ds;\n\
\n\
d$("txt_wsif_ds").onfocus = d$("txt_author").onfocus = woas.ui.focus_textbox;\n\
d$("txt_wsif_ds").onblur = d$("txt_author").onblur = woas.ui.blur_textbox;\n\
\x3C/script\x3E',
'= Deprecated syntax\n\
\n\
A summary of WoaS deprecated syntax; you are invited to _no more_ use deprecated syntax which is still supported because they will be declared /unsupported/ in some future release of WoaS.\x3Cstyle type="text/css"\x3E\n\
.bad_syntax {\n\
  color: red;\n\
  font-weight: bold;\n\
}\n\
.good_syntax {\n\
  color: green;\n\
  font-weight: bold;\n\
}\n\
\x3C/style\x3E\n\
== Lists\n\
\n\
Lists with \'+ sign are *unsupported*.\n\
\x3Cspan class="bad_syntax"\x3E{{{\n\
+ unordered lists with + sign\n\
+ unordered lists with + sign\n\
}}}\x3C/span\x3E\n\
\x3Cspan class="good_syntax"\x3E{{{\n\
* unordered lists with an asterisk\n\
* unordered lists with an asterisk\n\
}}}\x3C/span\x3E\n\
== Headers\n\
\x3Cspan class="bad_syntax"\x3E{{{! headers using the exclamation mark}}}\x3C/span\x3E\n\
\n\
\x3Cspan class="good_syntax"\x3E{{{= header which uses the equal sign}}}\x3C/span\x3E\n\
== Pre tags\n\
{{{\x3Cpre /\x3E}}} acting as nowiki blocks are *unsupported*. Now {{{\x3Cpre /\x3E}}} tags have no special meaning and are treated as any other XHTML tag.\n\
\n\
\x3Cspan class="bad_syntax"\x3EPre tags acting as &lt;pre&gt;nowiki&lt;pre &#047;&gt; blocks.\x3C/span\x3E\n\
\n\
\x3Cspan class="good_syntax"\x3EYou should use {\x3C!-- --\x3E{{nowiki}}\x3C!-- --\x3E} blocks instead.\x3C/span\x3E\n\
== Rulers\n\
\x3Cspan class="bad_syntax"\x3E{{{---\n\
horizontal rulers using only 3 hyphens}}}\x3C/span\x3E\n\
\n\
\x3Cspan class="good_syntax"\x3E{{{----\n\
You are invited to use at least 4 hyphens\n\
}}}\n\
== Tags\n\
\x3Cspan class="bad_syntax"\x3E{{{[[Tag::some tag|other tag|another tag]]}}}\x3C/span\x3E\n\
This syntax does not support transclusion of Tagged:: namespace; still supported but deprecated.\n\
\n\
\x3Cspan class="good_syntax"\x3E{{{[[Tag::some tag, some other tag]] and [[Tag::some tag]]}}}\x3C/span\x3E\n\
\n\
== Inline scripts\n\
\x3Cspan class="bad_syntax"\x3E{{{\x3Cscript\x3E...\x3C/script\x3E}}}\x3C/span\x3E\n\
\n\
\x3Cspan class="good_syntax"\x3E{{{\x3Cscript type="text/javascript"\x3E...\x3C/script\x3E}}}\x3C/span\x3E\n\
\n\
This is not enforced by WoaS wiki parser but is instead a correct XHTML practice.\n\
',
'= Options\n\
\n\
=== Use consistent newlines in saved data\n\
Forces pages to be saved using consistent newlines splitting. This is particularly useful if you use a versioning system like Subversion (SVN), git or CVS.\n\
\n\
=== Double click to edit pages/menu\n\
Allows to switch to edit mode when double-clicking the page content or menu area.\n\
\n\
=== Automatically save options (if changed) before quitting\n\
Allows option changes to be automatically saved without having to click the *Save options* button at the bottom of the page.\n\
\n\
=== Do not temporarily cache the AES key\n\
Clears AES key right after decryption, useful if you leave WoaS open to possible unauthorized access; will require to re-enter the decryption key each time you want to read a page.\n\
\n\
=== Fixed menu area and navigation bar\n\
Fixes the menu and navigation bar in place, while allowing the page to scroll.\n\
\n\
=== Return to last saved page when quitting\n\
Automatically opens the last saved page.\n\
\n\
=== Enable cumulative save\n\
Will save to disk only when quitting\n\
\n\
=== Disallow edits (button)\n\
Puts the wiki into /server mode/; users will be told that it is not possible to save their changes, but editing will be allowed for sandbox (testing) purposes.\n\
',
'= Embed %1\n\
\n\
\x3Cinput id="filename_" type="file" /\x3E&nbsp;\x3Cinput class="woas_button" type="button" value="Embed" onclick="woas._embed_process(\'%1\')" /\x3E',
'= Plugins\n\
This page contains options for the active WoaS plugins; see [[WoaS::Help::Plugins]] for more information.\n\
\x3Cinput class="woas_button" title="Create a new plugin" value="Create plugin..." onclick="javascript:_woas_new_plugin()" type="button" /\x3E&nbsp;&nbsp;\x3Cinput class="woas_button" title="Import a plugin" value="Import plugin..." onclick="go_to(\'Special::ImportWSIF\')" type="button" /\x3E',
'= Wiki on a Stick History\n\
\n\
== Versions 0.01 &tilde; 0.04\n\
\x3Csub\x3Eby Andr\u00e9 Wagner\x3C/sub\x3E\n\
\n\
As they say, /"necessity is the mother of invention"/. I needed a way to store information in a tree-like structure, but every software I tested felt like it was something missing. I tested a few mindmap software, tree structure software and personal wikis, but they were too complicated to install; I didn\'t yet have what I was looking for, or the tool wasn\'t closs-platform.\n\
\n\
The closest thing I found was [[http://www.tiddlywiki.com/|TiddlyWiki]], but it still wasn\'t perfect: it was too much blog-like, and what I needed was something wiki-like. So TiddlyWiki served as inspiration for the software I was about to create (I even used their saving routines).\n\
\n\
The core part of the code was written in one rainy afternoon. A few days later (after correcting most problems) I released it and the feedback I received was much more than I could ever expect. I guess that many other people had my same needs  :-) So this gave me motivation to continue working on Wiki on a Stick and to release three more versions.\n\
\n\
=== The principles\n\
Since the beginning I followed two basic principles: *simplicity* and *stability*. For simplicity I mean that the software should be easy enough for anyone to use, and the interface should be as plain as possible. And for stability I mean that the user data is sacred above all things, and the user should never loose his data, no matter what happens. I think these were the two facts that brought the good acceptance from the users.\n\
\n\
Unfortunatly, the duties of my graduation thesis made me stop working on WoaS and the software became dormant for a couple of months. It made me feel bad, since the mailing lists were at full throttle, with many people requesting features and sending patches that I couldn\'t even test.\n\
\n\
So I was very glad when Daniele offered himself to take over the task of managing the project. He did a great work and now WoaS is a much more rich application, with a even greater userbase. It feels really nice to see that people all around the world are using the software I created, and my desire is to see that WoaS grows in quality, features and userbase, and to remain a simple yet useful tool to everyone.\n\
\n\
== Versions 0.9.x\n\
\x3Csub\x3Eby Daniele C.\x3C/sub\x3E\n\
\n\
When I first found WoaS I felt that this software has a great potential; my first contribute to WoaS was to resolve all the bug tracker items and review the patches; the result was put into a v0.04G released in a SF.net patches tracker item (as attachment). That modified version was mostly a bug-fix and feature-fix modification, with small new features like custom keys for navigation and edits cancelling. V0.04G also missed the import feature (I forgot to add it back) and had a nasty double-click to edit feature which was not really good. That was my experimentation, I did not expect people to really use my modified version but since Andr\u00e9 had no time to review it, people was actually starting to use it.\n\
\n\
Some time later I took courage and asked to take-over the project; Andr\u00e9 Wagner kindly added me to the project as a developer and a project admin and I could start working on WoaS for real.\n\
\n\
My first big project management change was to switch to [[http://subversion.tigris.org/|Subversion (SVN)]] for the versioning of all our WoaS files; development could this way be fully documented and followed "live" by the mailing list (formerly google group) partecipants, which are the first solid community gathered around WoaS.\n\
\n\
Version 0.9B was the first official version which I worked on. My first big change was to have storage of pages not in content-escaped hidden divs but as javascript strings; this brought more speed to the page loading process. I also had to solve some problems inherent to the double file vs single file compatibility (WoaS can since then work with the 2-files version and single file version) and some IE saving issues, but finally the result was good enough.\n\
\n\
A lot of features and improvements have been implemented during the (still current) v0.9.x development cycle, without never slowing down some parts of WoaS for each new feature implemented (further speed optimizations will be engineered when the codebase is stable enough); we are as always gathering the users\' feedback to add usability and more powerful features to WoaS. Such features must of course be coherent with WoaS principles and base philosophy.\n\
\n\
=== Object orienting\n\
\n\
Wiki on a Stick codebase has been rewritten as object-oriented in order to be more maintanable and modular (the development version contains multiple javascript source files which are as always merged into one before releases). Such process is not yet complete and is being carried out during the 0.12.x development.\n\
\n\
== 0.10.x\n\
\n\
Development of 0.9.7B was stale and WoaS was getting full of little bugs which prevented it from being successfully used; during last months of 2009 and first months of 2010 WoaS got new blood with 0.10.x releases.\n\
Some of the best additions were [[WoaS::Help::WSIF|WSIF format]] and a pluggable macro syntax, but finally the product had reached the stability which its users deserved and exited its Beta status to enter a Production development stage.\n\
\n\
== 0.11.x\n\
\n\
The 0.11.x development stage is focusing new features and fixing old bugs; there have been many new important enchancements like access keys.\n\
\n\
== 0.12.x\n\
\n\
During development of 0.12.0 plugins support has been added and code has been re-organized for modularity.\n\
',
'= Export content into XHTML files\n\
\n\
==Paths\n\
Specify the destination directory which will contain all the exported XHTML files.\n\
\n\
Note: *Directory must exist if using a non-Mozilla browser.*\n\
\n\
\x3Cinput id="woas_ep_xhtml" type="text" size="80" /\x3E\n\
\n\
Specify the destination directory which will contain all the exported embedded pictures.\n\
\n\
Note: *Directory must exist if using a non-Mozilla browser.*\n\
\n\
\x3Cinput id="woas_ep_img" type="text" size="80" /\x3E\n\
\n\
==File naming\n\
\n\
Default extension for generated XHTML files\n\
\n\
\x3Cinput id="woas_ep_ext" type="text" size="8" /\x3E\n\
\n\
\x3Clabel for="woas_cb_index_main"\x3E\x3Cinput type="checkbox" id="woas_cb_index_main" checked="checked"\x3EThe main page will be named index.htm\x3C/label\x3E\n\
\x3Clabel for="woas_cb_unix_norm"\x3E\x3Cinput type="checkbox" id="woas_cb_unix_norm" checked="checked"\x3EApply UNIX-style normalization (lowercase and spaces replaced by underscores) to generated filenames\x3C/label\x3E\n\
\n\
==Custom JavaScripts\n\
\x3Clabel for="woas_cb_js_ign"\x3E\x3Cinput type="radio" id="woas_cb_js_ign" name="woas_cb_js" checked="checked"\x3EDo not export\x3C/label\x3E\n\
\x3Clabel for="woas_cb_js_dyn"\x3E\x3Cinput type="radio" id="woas_cb_js_dyn" name="woas_cb_js"\x3ERun before exporting but do not export the javascript\x3C/label\x3E\n\
\x3Clabel for="woas_cb_js_exp"\x3E\x3Cinput type="radio" id="woas_cb_js_exp" name="woas_cb_js"\x3EExport javascript as-is\x3C/label\x3E\n\
\x3Clabel for="woas_cb_js_head"\x3E\x3Cinput type="radio" id="woas_cb_js_head" name="woas_cb_js" disabled="disabled"\x3EExport javascript into &lt;head /&gt; (you might need to include the framework code)\x3C/label\x3E\n\
\n\
\x3Clabel for="woas_cb_js_fw"\x3E\x3Cinput type="checkbox" id="woas_cb_js_fw" disabled="disabled"\x3EExport the javascript framework too\x3C/label\x3E\n\
\n\
==Other options\n\
META author (optional)\n\
\n\
\x3Cinput id="woas_ep_author" type="text" size="12" value="" /\x3E\n\
\n\
\x3Clabel for="woas_cb_sep_css"\x3E\x3Cinput type="checkbox" id="woas_cb_sep_css" checked="checked"\x3EExport CSS into shared file\x3C/label\x3E\n\
\x3Clabel for="woas_cb_export_menu"\x3E\x3Cinput type="checkbox" id="woas_cb_export_menu" checked="checked"\x3EExport menu and submenus\x3C/label\x3E\n\
\n\
\x3Cinput class="woas_button" type="button" value="Export XHTML" onclick="woas.export_wiki()" /\x3E\n\
\n\
\x3Cscript type="text/javascript"\x3E\n\
var path = woas.ROOT_DIRECTORY + "export" + woas.DIRECTORY_SEPARATOR;\n\
d$(\'woas_ep_xhtml\').value = path;\n\
d$(\'woas_ep_img\').value = path;\n\
d$(\'woas_ep_ext\').value = woas.exporter._default_ext;\n\
\n\
d$(\'woas_ep_xhtml\').onfocus = d$(\'woas_ep_img\').onfocus = d$(\'woas_ep_ext\').onfocus = woas.ui.focus_textbox;\n\
d$(\'woas_ep_xhtml\').onblur = d$(\'woas_ep_img\').onblur = d$(\'woas_ep_ext\').onblur = woas.ui.blur_textbox;\n\
d$(\'woas_ep_author\').value = woas.config.wsif_author;\n\
\n\
\x3C/script\x3E',
'= Special::License\n\
\n\
Retrieved from [[http://www.gnu.org/licenses/gpl2.txt]]:\n\
\n\
\x3Ciframe border="0" width="100%" height="300" src="http://www.gnu.org/licenses/gpl2.txt"\x3E\x3C/iframe\x3E',
'# all lines not starting with \'$\' are ignored\n\
$JS  Javascript',
'= Export into WSIF format\n\
\n\
See also [[WoaS::Help::WSIF]].\n\
\n\
== Destination path\n\
Destination directory that will contain the exported WSIF file(s).\n\
\n\
Note: *Directory must exist if using a non-Mozilla browser.*\n\
\n\
\x3Cinput id="woas_ep_wsif" type="text" size="80" /\x3E\n\
\n\
== File generation\n\
\n\
\x3Clabel for="woas_cb_single_wsif"\x3E\x3Cinput type="checkbox" id="woas_cb_single_wsif" checked="checked"\x3EExport all pages into a single WSIF file\x3C/label\x3E\n\
\x3Clabel for="woas_cb_inline_wsif"\x3E\x3Cinput type="checkbox" id="woas_cb_inline_wsif"\x3EDo not export embedded files as external file blobs\x3C/label\x3E\n\
\n\
== Other options\n\
Author: \x3Cinput id="woas_ep_author" type="text" size="12" value="" /\x3E\n\
\n\
\x3Cinput class="woas_button" type="button" value="Export WSIF" onclick="woas.export_wiki_wsif()" /\x3E\n\
\n\
\x3Cscript type="text/javascript"\x3E\n\
var path = woas.ROOT_DIRECTORY + "wsif" + woas.DIRECTORY_SEPARATOR;\n\
d$(\'woas_ep_wsif\').value = path;\n\
\n\
d$(\'woas_ep_author\').onfocus = $(\'woas_ep_wsif\').onfocus = woas.ui.focus_textbox;\n\
d$(\'woas_ep_author\').onblur = $(\'woas_ep_wsif\').onblur = woas.ui.blur_textbox;\n\
d$(\'woas_ep_author\').value = woas.config.wsif_author;\n\
\n\
\x3C/script\x3E',
'= WSIF\n\
\n\
*W*iki on a *S*tick *I*nterchange *F*ormat is the preferred format for exporting full WoaS data into a single file and share it with whoever you like.\n\
\n\
== Format description\n\
\n\
WSIF format is similar to MIME email attachments format; each line comes like an /email header/ definition, as in following example:\n\
\n\
{{{header.name: header-value}}}\n\
\n\
All WSIF content must be ASCII, so /header-value/ must be ECMA-escaped when necessary; this corresponds to escaping slashes "\\" to "\\\\" and any UTF-8 sequence to the corresponding "\\u0000" string, where /0000/ is the lowercase hexadecimal value of the UTF-8 character (like in ECMAScript).\n\
\n\
WSIF files can contain custom headers, given that the following namespaces are currently reserved for official WSIF format support:\n\
* *wsif*\n\
* *woas*\n\
\n\
For example you could define a new namespace for header definitions called /custom/:\n\
\n\
{{{\n\
custom.x: 100\n\
custom.y: 200\n\
custom.content: Hello world!\n\
}}}\n\
It is up to you then to parse such header-value couples and give them proper representation.\n\
== Inline boundaries\n\
\n\
A line starting with two dashes (/--/) introduces an *inline boundary*, which is a properly encoded snippet.\n\
\n\
Example boundary:\n\
\n\
{{{\n\
--my-random-id\n\
this is the inline snippet\n\
--my-random-id\n\
}}}\n\
/my-random-id/ must be a (usually random) string *unique inside the boundary content*, but it does not need to be unique inside the whole WSIF file, which must be read sequentially (like in a state machine).\n\
\n\
= wsif namespace\n\
\n\
The *wsif.* namespace currently defines only an information header:\n\
\n\
* *wsif.version* - WSIF format version into which content is offered\n\
* *wsif.generator* - program/library used to generate WSIF content\n\
Version 1.1.0 and above are currently supported.\n\
= woas namespace\n\
\n\
The *woas.* namespace defines general WoaS content properties and specific WoaS pages; the following headers are defined for general context:\n\
\n\
* *woas.version* - version of WoaS used to produce the WSIF file\n\
* *woas.pages* - total count of WoaS pages stored inside WSIF file\n\
\n\
The following are header definitions specific for WoaS pages:\n\
\n\
* *woas.page.title* - ECMA-escaped page title; this header has a special meaning because it is the page start marker inside the state machine; it is suggested that WSIF implementations write it as first header for page definition stanzas;\n\
* *woas.page.attributes* - a positive integer value in decimal format specifying the page attributes;\n\
* *woas.page.last_modified* - a positive integer value in decimal format representing seconds lasted from the UTC epoch up to last modified time; this header is defined only if data is available from WoaS;\n\
* *woas.page.length* - content length of the inline snippet; only inline files define it; this is not the decoded page length but the length of the content inside the inline boundaries;\n\
* *woas.page.original_length* - real page length as seen by WoaS; it is currently defined only for encrypted pages;\n\
* *woas.page.encoding* - snippet encoding format, see the *Encoding* section below;\n\
* *woas.page.disposition* - tells whether page is /inline/ or /external/;\n\
* *woas.page.boundary* - string used for inline boundary recognition (without leading dashes); this header is specified only for inline snippets;\n\
* *woas.page.disposition.filename* - filename used for external page content, not ECMA-escaped; defined only with external pages;\n\
* *woas.page.mime* - mime type of external pages which have a defined mime type, like images for example;\n\
\n\
All headers are mandatory (under their specific state definition branch), except /last_modified/ and /original_length/.\n\
\n\
= Encoding\n\
\n\
The *woas.page.encoding* header can contain one of the following values:\n\
\n\
* *8bit/plain* - data is ASCII text which can use 8bits to represent characters; only ASCII text should be used and not UTF-8;\n\
* *ecma/plain* - data is ECMA-escaped UTF-8 text;\n\
* *8bit/base64* - data is base64-encoded binary data;\n\
* *text/wsif* - data is WSIF (currently used only for external WSIF pages)\n\
\n\
Pages or header values are encoded in *ecma/plain* format when UTF-8 sequences are found inside the value string, otherwise *8bit/plain* is used; *8bit/base64* is instead used for binary files or encrypted pages.\n\
\n\
= Usage notes\n\
\n\
WSIF format is pretty straightforward to produce or interpret, however please consider the following facts:\n\
\n\
* *woas.page.disposition.filename* must be plain ASCII (this limitation might be removed in future versions of the format) and should be a relative filename;\n\
* it is safe to embed a WSIF file inside another, given that boundaries are properly implemented\n\
\n\
WoaS project offers an official PHP library (libwsif) for reading/writing WSIF files, as well as a documented example.',
'Import a wiki page (or collection of) in [[WoaS::Help::WSIF|WSIF format]].\n\
\n\
File: \x3Cinput id="filename_" type="file" /\x3E&nbsp;\x3Cinput id="btn_import" class="woas_button" type="button" value="Import WSIF" onclick="woas.import_wiki_wsif()" /\x3E\n\
\n\
[[Include::WoaS::ImportSettings]]\n\
\n\
\x3Cscript type="text/javascript"\x3E\n\
woas.ui._import_wsif_load();\n\
\x3C/script\x3E',
'= Macros\n\
\n\
Wiki on a Stick (version 0.10.7 and above) supports wiki macros for pluggable wiki syntax.\n\
\n\
== Definition\n\
\n\
A macro block is defined as follows:\n\
\n\
{{{\x3C\x3C\x3C ... the macro content here ... \x3E\x3E\x3E}}}\n\
\n\
However the above macro example is not parsed in any particular way by WoaS. If you want to run a plugged-in parser on the macro content you should use this syntax instead:\n\
\n\
{{{\x3C\x3C\x3Cmacroname:\n\
24\n\
56\n\
89\n\
28\n\
19\n\
33\n\
\x3E\x3E\x3E}}}\n\
\n\
= Real example\n\
\n\
For example, let\'s define the sum macro:\n\
\n\
{{{\x3C\x3C\x3C%my_sum:\n\
\n\
  var elements = macro.text.split(/[\\s\\n]+/), total = 0;\n\
  for (var i=0,l=elements.length;i\x3Cl;++i) {\n\
    if (!elements[i].length) continue;\n\
    try { total += parseInt(elements[i]); } catch(e) { }\n\
  }\n\
  macro.text = total.toString();\n\
\x3E\x3E\x3E}}}\n\
\x3C\x3C\x3C%my_sum:\n\
\n\
  var elements = macro.text.split(/[\\s\\n]+/), total = 0;\n\
  for (var i=0,l=elements.length;i\x3Cl;++i) {\n\
    if (!elements[i].length) continue;\n\
    try { total += parseInt(elements[i]); } catch(e) { }\n\
  }\n\
  macro.text = total.toString();\n\
\x3E\x3E\x3E\n\
Note that macro definition happens with the special \'%\' sign before the macro name. Macros cannot be overriden with the macro definition.\n\
Such defined macro uses the macro object which has two standard properties:\n\
* *reprocess* - set to true when text can be re-processed by WoaS parser (default false)\n\
* *text* - the content of macro block after the double colon\n\
\n\
Now we call the macro:\n\
\n\
{{{\x3C\x3C\x3Cmy_sum:\n\
24\n\
56\n\
89\n\
28\n\
19\n\
33\n\
\x3E\x3E\x3E}}}\n\
\n\
And this is the actual result:\n\
\x3C\x3C\x3Cmy_sum:\n\
24\n\
56\n\
89\n\
28\n\
19\n\
33\n\
\x3E\x3E\x3E\n\
\n\
== Macros with arguments\n\
Starting with WoaS 0.12.0 macros do support named arguments and should return a true/false value to tell about their success/failure at rendering the macro text.\n\
\n\
Example:\n\
{{{\x3C\x3C\x3C%my_arg_macro(name, color):\n\
\n\
macro.text = "\x3Cstrong\x3E"+name+"\x3C/strong\x3E says: \x3Cspan style=\\"color: "+color+"\\"\x3E"+macro.text+"\x3C/span\x3E";\n\
\n\
return true;\n\
\n\
\x3E\x3E\x3E}}}\x3C\x3C\x3C%my_arg_macro(name, color):\n\
macro.text = "\x3Cstrong\x3E"+name+"\x3C/strong\x3E says: \x3Cspan style=\\"color: "+color+"\\"\x3E"+macro.text+"\x3C/span\x3E";\n\
return true;\n\
\x3E\x3E\x3E\n\
Which is then called with:\n\
\n\
{{{\x3C\x3C\x3Cmy_arg_macro("Simon", "green"):\n\
I have 3 fruits in my basket\n\
\x3E\x3E\x3E}}}\n\
And the result is:\n\
\n\
\x3C\x3C\x3Cmy_arg_macro("Simon", "green"):\n\
I have 3 fruits in my basket\n\
\x3E\x3E\x3E\n\
\n\
The passed arguments must be valid JavaScript expressions.\n\
\n\
== Global macros\n\
Macros can be available on all pages if they are registered by plugins.\n\
\n\
In order to define a global macro you should create or edit a plugin and then add JavaScript code like this:\n\
\n\
{{{woas.macro.register(\'my.arg_macro\', function(macro, name, color) {\n\
macro.text = "\x3Cstrong\x3E"+name+"\x3C/strong\x3E says: \x3Cspan style=\\"color: "+color+"\\"\x3E"+macro.text+"\x3C/span\x3E";\n\
return true;\n\
});\n\
}}}\n\
',
'= Help index\n\
The first time you save a change to Wiki on a Stick, your browser will ask for permission to save data to the disk. This is normal and necessary for the wiki to make changes to itself. You can give permission each time or make the setting permanent.\n\
\n\
You will find the *Help* icon in the navigation bar on every page in this wiki. When you click on it, it will either open this page or a specific help page that explains how to work with the page you currently have open.\n\
\n\
When browsing the pages in this Help pop-up, you will find a *Back* button in the upper right corner that takes you back to this page or a *Close* button in the same place that closes the pop-up.\n\
== Contents:\n\
* *Features*\n\
** [[WoaS::Help::Security]]\n\
** [[WoaS::Help::WSIF]]\n\
* *Interface*\n\
** [[WoaS::Help::Aliases]]\n\
** [[WoaS::Help::CSS]]\n\
** [[WoaS::Help::Edit the menu]]\n\
** [[WoaS::Help::Editor]]\n\
** [[WoaS::Help::Export]]\n\
** [[WoaS::Help::General usage]]\n\
** [[WoaS::Help::Hotkeys]]\n\
** [[WoaS::Help::Import]]\n\
** [[WoaS::Help::Requirements]]\n\
* *Online use*\n\
** [[WoaS::Help::Publish wiki online]]\n\
** [[WoaS::Help::Run wiki on a webserver]]\n\
* *Page management*\n\
** [[WoaS::Help::Create a page]]\n\
** [[WoaS::Help::Delete a page]]\n\
** [[WoaS::Help::Edit a page]]\n\
** [[WoaS::Help::Erase all pages]]\n\
** [[WoaS::Help::Namespaces]]\n\
** [[WoaS::Help::Page scrolling]]\n\
** [[WoaS::Help::Rename a page]]\n\
* *Specific Help pages*\n\
** [[WoaS::Help::Special::Advanced]]\n\
** [[WoaS::Help::Special::Dead Pages]]\n\
** [[WoaS::Help::Special::Erase Wiki]]\n\
** [[WoaS::Help::Special::ExportWSIF]]\n\
** [[WoaS::Help::Special::ImportWSIF]]\n\
** [[WoaS::Help::Special::Options]]\n\
[[Include::WoaS::Help::Syntax]]\n\
* *Troubleshooting*\n\
** [[WoaS::Help::Wiki is read-only]]',
'* *Syntax*\n\
** [[WoaS::Help::Deprecated syntax]]\n\
** [[WoaS::Help::Headers]]\n\
** [[WoaS::Help::Images]]\n\
** [[WoaS::Help::Include text file]]\n\
** [[WoaS::Help::Include web page]]\n\
** [[WoaS::Help::Include wiki page]]\n\
** [[WoaS::Help::JavaScript]]\n\
** [[WoaS::Help::Join lines of text]]\n\
** [[WoaS::Help::Links]]\n\
** [[WoaS::Help::Lists]]\n\
** [[WoaS::Help::Macros]]\n\
** [[WoaS::Help::Nowiki text]]\n\
** [[WoaS::Help::Rulers]]\n\
** [[WoaS::Help::Table of Contents]]\n\
** [[WoaS::Help::Tables]]\n\
** [[WoaS::Help::Tags]]\n\
** [[WoaS::Help::Text formatting]]\n\
** [[WoaS::Help::Transclusion]]',
'\x3Cinput type="button" class="woas_button woas_help_button" value="%1" title="%1" onclick="%2"\x3E',
'= Advanced\n\
The Advanced page offers some tools for administration of your wiki. Descriptions are provided, and most of the Special links lead to pages that have individual help available. Below are links to help pages for the ones that don\'t offer individual help automatically.\n\
* *WoaS::CSS::Core* and *WoaS::CSS::Custom* -  See the [[WoaS::Help::CSS]] page.\n\
* *WoaS::Plugins* - See the [[WoaS::Help::Plugins]] page.\n\
* *WoaS::Aliases* - See the [[WoaS::Help::Aliases]] page.\n\
* *WoaS::Hotkeys* - See the [[WoaS::Help::Hotkeys]] page.\n\
* *Special::Erase Wiki* - See the [[WoaS::Help::Special::Erase Wiki]] page\n\
',
'= Erase Wiki\n\
When you click the *Special::Erase Wiki* link in the {{{[[Special::Advanced]]}}} page you can erase all user-created pages. Doing this will also erase the {{{[[Main Page]]}}} and all content from the menu, which will then be re-populated with some common-use Special:: links. Global core CSS settings will be preserved, while the {{{[[WoaS::CSS::Custom]]}}} page will be reset to default values.\n\
\n\
If you have not given permanent permission to your browser for editing wiki pages, you will receive a security warning when attempting to erase the wiki. If you deny permission to the browser, you will receive a message that saving the file failed. You will be returned to your wiki, but the Main Page will be blank. Reloading the wiki after a failure to save restores WoaS to the previous status.\n\
',
'= CSS\n\
The look and feel of WoaS can be customized by specifying custom CSS in the [[WoaS::CSS::Custom]] reserved page. You shall use WoaS core CSS definitions available in [[WoaS::CSS::Core]] as a reference when you are writing CSS customization.\n\
\n\
\x3C\x3C\x3Cwoas.include:WoaS::Template::Info\n\
A tutorial about CSS is available at [[http://www.w3schools.com/css/]].\x3E\x3E\x3E\n\
== Customizing CSS\n\
# Access [[WoaS::CSS::Core]] either directly or from [[Special::Advanced]]\n\
# Copy the CSS definitions you want to customize\n\
# Access [[WoaS::CSS::Custom]] either directly or from [[Special::Advanced]]\n\
# Edit the page and paste the classes and ids you copied in previous step\n\
# Define the rules for the CSS classes and ids.\n\
# Save your changes by clicking the *Save* icon in the navigation bar.\n\
\n\
All changes will be visible immediately.\n\
\n\
== Restore the default CSS settings\n\
You can always restore WoaS default CSS by deleting the content of [[WoaS::CSS::Custom]].\n\
\n\
== Import CSS rules into your wiki\n\
You can import the CSS rules from another copy of WoaS by following the instructions for [[WoaS::Help::Import|importing]] another wiki into the current one and placing a check in the box next to *Import also CSS.*\n\
\n\
Importing from older versions of WoaS can garble the layout of the wiki. There are two ways to avoid this:\n\
# Manually transfer the CSS from the older version of WoaS into the [[WoaS::CSS::Custom]] page by copying and pasting it, checking the class and id of each entry against the default CSS rules on the [[WoaS::CSS::Core]] page to verify that it\'s still in use before saving your changes.\n\
# Create a new page with style tags in it and paste your CSS into that page to test it before adding it to the [[WoaS::CSS::Custom]] page.\n\
\n\
=== Create a test page for your custom CSS\n\
# Access [[Special::Options]] either directly or from [[Special::Advanced]]\n\
# Make sure that the box is /not/ checked next to *Remember current page and navigation history*. Save the change if you had to uncheck the box.\n\
# Create a [[Special::New Page|new page]]\n\
# Insert this opening tag at the top of the page:\x3Cbr/\x3E{{{\n\
\x3Cstyle type="text/CSS"\x3E\n\
}}}\n\
# Paste your CSS rules beneath the tag.\n\
# Insert this closing tag at the bottom of the page:\x3Cbr/\x3E{{{\n\
\x3C/style\x3E\n\
}}}\n\
# Save changes\n\
\n\
Once you have tested your CSS on a single page you can choose whether to move such CSS definitions to [[WoaS::CSS::Custom]] or not.',
'= Dead Pages\n\
This page displays a list of pages that contain links to nonexistent pages. Both the link and the page it\'s on are shown in each entry.\n\
\n\
Fixing dead pages is a good way to not break end-user browsing experience.',
'= General usage\n\
\n\
== Cancel any action\n\
Cancel any action by clicking the *Cancel* icon in the navigation bar, clicking the *Cancel* button on any alert that pops up, or pressing the *Esc* key.\n\
\n\
== Navigation\n\
Use the *Back* and *Forward* arrow icons in the navigation bar to go back or forward one page, the *Main Page* icon in the navigation bar to return to the {{{[[Main page]]}}}, or click the buttons and links in the menu and wiki pages.\n\
\n\
== Pages linking to the current page\n\
Click the *Backlinks* link in the menu to see which pages link to the page you currently have open.\n\
\n\
== Print a page\n\
Click the *Print* icon in the navigation bar. A new browser window will open with a printer-friendly version of the main text area. Use the browser\'s print functions to print the page.\n\
\n\
== Syntax\n\
This wiki accepts plain text, WoaS wiki syntax, and XHTML. See the *Syntax* section of the [[WoaS::Help::Index|Help index]] by clicking the *Help* icon in the navigation bar for help with using the syntax in your pages.\n\
\n\
[[Include::WoaS::Template::Info|WoaS syntax is partially compatible with Creole 0.1 syntax.]]\n\
',
'= Nowiki text\n\
/Nowiki text/ is a section of raw or preformatted text that is not parsed as wiki syntax. Anything you place inside nowiki brackets will be displayed in monospace font exactly as you typed it.\n\
\n\
== Multi-line blocks\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\n\
\x3Cdiv class="woas_helpcode"\x3E{\\\n\
{{\n\
This is a code block\n\
made of one\n\
or more lines.\n\
}}\\\n\
}\x3C/div\x3E\n\
\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
{{{\n\
This is a code block\n\
made of one\n\
or more lines.}}}\n\
== Inline nowiki blocks\n\
\n\
A normal sentence can contain an inline nowiki block, like {{\x3C!-- --\x3E{this block}}\x3C!-- --\x3E}.\n\
\n\
Example (with the mathematical equation inside a nowiki block):\n\
\n\
The equation {{{E = mc^2}}} indicates that energy always exhibits mass in whatever form the energy takes.\n\
\n\
== Nowiki blocks inside lists\n\
A nowiki block can be added to a list item by inserting the opening curly brackets at the end of the list item.\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\n\
\x3Cdiv class="woas_helpcode"\x3E* List item:&#123;&#123;&#123;\n\
This is a code block\n\
made of one\n\
or more lines.\n\
&#125;&#125;&#125;\x3C/div\x3E\n\
\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
* List item:{{{\n\
This is a code block\n\
made of one\n\
or more lines.\n\
}}}\n\
\n\
To insert a newline between the list item and the nowiki block, you can use HTML {{{\x3Cbr\x3E}}} tags before the opening curly brackets.\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\n\
\x3Cdiv class="woas_helpcode"\x3E* List item:&lt:br&gt;&lt;br&gt;&#123;&#123;&#123;\n\
This is a code block\n\
made of one\n\
or more lines.\n\
&#125;&#125;&#125;\x3C/div\x3E\n\
\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
* List item:\x3Cbr\x3E\x3Cbr\x3E{{{\n\
This is a code block\n\
made of one\n\
or more lines.\n\
}}}\n\
\n\
== Nowiki block with custom CSS style\n\
The example uses /lightcyan/ and /purple/ colors, but you can replace those with whatever colors you like, using [[http://www.w3schools.com/Html/html_colornames.asp|color names or hexadecimal notation]].\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cdiv class="woas_helpcode"\x3E\n\
&lt;span style="background-color:lightcyan; color:purple;"&gt;&#123;&#123;&#123;\n\
This is a code block\n\
made of one\n\
or more lines.\n\
&#125;&#125;&#125;&lt;/span&gt;\n\
\x3C/div\x3E\n\
\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Cspan style="background-color:lightcyan; color:purple;"\x3E{{{\n\
This is a code block\n\
made of one\n\
or more lines.\n\
}}}\x3C/span\x3E\n\
',
'\x3Cdiv style="background-color: #FFFFAA; border: 0.1em solid; padding: 0.2em;"\x3E\x3Cimg src="%2FAAAAAAABAQEBAQECAgICAwMDBAQFBQUABgYGCQgJCgoLDAsMDQwPDQ0NDw4PDw8HEhETExMUFRQUGRkNGhsUGxscHx8eISATIR8lJCQVJiUsJyUqKCcuLCwtLiw0Ly4vMzE4NzYoQT9FQz9ERkZGSkdTS0hMTEhNUk5bU1JVY15kYWBkZWFubGh5bmt1cGt6c212cm5%2BcXFwfHaDfXxehoKQjIiUkYyfkoyllZKal5CpmJGqmJGrmZKtmpaim5WunJaunZewn5mxoJqyopquoZuxpJylopyyopy1pJ22pJ24pJ61pJ%2B1paC1pqC1qaC0pqG1qKG7qqKuqaKxqKK4paWkq6O7qaS3q6p%2BraW4rae6rKmvrqm1rqm6r6nDsKu1sKu9sKu%2Bs6yxs7GDsay9sq29s667tK7FuK%2FBtbDAtbDBt7HEubS%2BubTCurTKurXFvLqjvLfGvLjEv72LvL2VvbjLvr%2BPwL%2BKvbvBw7nHv7vDwMGHw7rHwb3Fwr3Lw8SQxb%2FRxsDRxsHMxcLGxsPLyMPQx8XKyMXIysuOycbIzMfVzcrMz8zU0NGi0czZ0M%2FL0c%2FL0c%2FN0s7X08%2FZ1NPN1ten1tTR1tXP19XS2tfc3Nyt3N2s3dni397W4N%2FX4N%2FZ4t7m4eDY4t%2Fm4eHY4uHb4uDl4uLX4%2BLa5OLo5OTb5ubd6OjJ6Ofh6erE6efr6efs6ujs6%2Bju6%2B3B6%2Brj6%2Bnt6%2Brl7O6%2F6%2Bvk7Ovr7Ovu7evu7vDC7ezv7e3p7u7p7%2B7w7%2B7x7%2B%2Fx8fPF8PDt8e%2F18fDs8fDy8fDz8%2FXC8fHx8%2FD38vLt8vLu8vL08%2FPt8%2FPu9PP09vjI9fXw9vX09vbx9%2FX59%2Fby9%2Fb39%2Ffx%2BPf4%2Bfj5%2Bfj6%2Bfnz%2Bfn1%2Bfr1%2B%2F7K%2Bvr2%2B%2Fr5%2FPr%2F%2B%2Fv7%2FP%2FR%2Ffv%2B%2Ffz9%2F%2F7%2FFnlyNwAAAAF0Uk5TAEDm2GYAAAABYktHRACIBR1IAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH2gMHDxg0DfX8UQAAAUBJREFUKM9jYCAIGBl5hLgYGTGEuXViWpvTzZVZUaUYFdofXzu4YW53o5kgsgyj3LIXFy8e2rphclaZBS%2BSDHvlsxvPb5%2FbtXFKQVyGHkKCUev08TtPbp3Yu7KtKMnfUxIuw2h19MCVu9dP7Z41c3qeR5AmXII1YdOuy%2Ffv3dyyZMfqLhdvA7gEZ%2BzC9UcePrp6%2Fuz%2B%2BdWOXiYIo%2Bz7F%2B%2B8cGb5qkUz6vxsww0REvpN9b3zjq3oKU7zcbLOVEdIyOSkZk%2FatrYj1NfZNiCYH8mDuvmB1Qv2TYxwsHGt0kDyICObUXz01KUT3OyiarVRAouJWc0ysSU3JNldBT18mYUL16ybXaHEiBkfNQ%2B290WKyGNKNFzaMy1FQhZTovzp4TklUtKYEp0nN5eaCihiSPBxiIapMopjSw5iLIzGhBMNAHCEbLFZHo5dAAAAAElFTkSuQmCC" alt="Info" border="0" /\x3E %1\x3C/div\x3E',
'= Wiki is read-only\n\
If you have a read-only copy of WoaS and you want a write-enabled copy you should ask the author to provide it; read-only protection is by no way a security mechanism (see [[WoaS::Help::Security]]), but instead a /fair use/ invite e.g. you disable the write features because you assume that they won\'t be useful to end-user.\n\
\n\
If you want to re-enable the write features manually you should:\n\
# Back up your WoaS\n\
# Open it in a text editor\n\
# Do a search for: {{{"permit_edits":false,}}}\n\
# Replace it with: {{{"permit_edits":true,}}}\n\
# Save the file\n\
\n\
*NOTE:* this way of re-enabling WoaS write mode is *unsupported*, e.g. it might not work in future versions of WoaS.',
'= Create a page\n\
# Access [[Special::New Page]]\n\
# Type the page title. Maximum length is 256 characters, although you might want to use a shorter title to not interfere with the navigation bar. Page titles are case sensitive, all characters are allowed except angled brackets, square brackets, curly braces and pipe characters ("&lt;&gt;[]{}|")\n\
# Press the *Enter* key or click the *OK* button\n\
# When asked if you\'d like to add a link into the main menu, accept by pressing the *Enter* key or clicking the *OK* button, or refuse by pressing the Escape key or clicking the *Cancel* button\n\
# Edit the contents of the main text area by typing normally. You can freely change the default text (a level one header with the page name)\n\
# Use the editor\'s buttons to insert wiki syntax to format the text or type the wiki syntax manually (plain text does not need any wiki syntax)\n\
# Save your changes\n\
\n\
== Create a missing page\n\
\n\
An alternate method of creating a page is to type a new page title inside square brackets and then attempt to access the unexisting page.\n\
\n\
*Example:*\n\
{{{\n\
[[My new page]]\n\
}}}\n\
\x3Cdiv class="woas_helptext"\x3EIs rendered as:\x3C/div\x3E\n\
[[My new page]]\n\
\n\
= Troubleshooting\n\
There are some issues which could prevent you from creating a page.\n\
\n\
* You didn\'t type a title for the page in the input box that popped up\n\
* There is already a page by that title\n\
* The wiki is being run in [[WoaS::Help::Publish wiki online|read-only mode]], so no changes are allowed. See the [[WoaS::Help::Wiki is read-only]] page for instructions on how to return the wiki to editing mode\n\
* You are trying to use a [[WoaS::Help::Namespaces|namespace]] that is reserved by WoaS. In this case a message will pop up letting you know the namespace is reserved and giving you an opportunity to choose a different title/namespace for the page\n\
',
'= By action link\n\
# Access [[Special::Delete Page]] directly or either from [[Special::Advanced]]\n\
# You\'ll be asked for the exact title of the page and then for confirmation\n\
# When the page is deleted, you\'ll be returned to the page you were on before deleting the page.\n\
\n\
= By editing\n\
# Edit the page you wish to delete\n\
# Select everything inside the main text area and delete it\n\
# Save your changes, you will be asked for deletion confirmation\n\
\n\
= References to deleted pages\n\
Access [[Special::Dead Pages]] directly or either from [[Special::Advanced]] to remove references to the deleted page',
'= Editor features\n\
* Cancel all changes by clicking the *Cancel* icon in the navigation bar at any time.\n\
* Change the title of a page by editing the contents of the *Page title* box.\n\
* Save all changes by clicking the *Save* icon in the navigation bar at any time.\n\
* See an example of how tables are built by clicking the *About tables* link.\n\
* Toggle the display of the button rows by clicking the *Show/Hide wiki buttons|Show/Hide XHTML buttons* links.\n\
\n\
== Wiki buttons\n\
Buttons to ease printing [[WoaS::Help::Syntax|wiki syntax]].\n\
{|\n\
|+ Wiki Code buttons\n\
| *Button* || *What it does*\n\
| Wiki URL || Add a wiki link to a page.\n\
| URL || Add an external link to a page.\n\
| {{{=}}} || Insert wiki syntax for a level one header. Use this at the beginning of any line.\n\
| {{{==}}} || Insert wiki syntax for a level two header. Use this at the beginning of any line.\n\
| Img || Include a wiki image in the page.\n\
| *B* || Wrap selected text with bold syntax.\n\
| /i/ || Wrap italic text with bold syntax.\n\
| u || Wrap selected text with underline syntax.\n\
| &#123;&#123;&#123; &#125;&#125;&#125; || Wrap wiki syntax around the selected text to make it nowiki (raw) text.\n\
| * || Insert the wiki syntax for a bulleted list item.\n\
| # || Insert the wiki syntax for a numbered list item.\n\
| @ || Insert the wiki syntax for an alphanumeric list item.\n\
| Ruler || Insert a ruler (horizontal line). Use this at the beginning of any line.\n\
| Tags || Interface for inserting tags in your page to categorize it. Use a comma between multiple tags.\n\
|}\n\
\n\
*Note:* it\'s recommended to use [[WoaS::Help::Syntax|wiki syntax]] instead of XHTML syntax, because this is a wiki.\n\
\n\
== XHTML buttons\n\
{|\n\
|+ XHTML Code buttons\n\
| *Button* || *What it does*\n\
| *B* || Wrap selected text with bold tags.\n\
| /i/ || Wrap selected text with emphasis tags (italics).\n\
| u || Wrap selected text with underline tags.\n\
| s || Wrap selected text with strike-through tags.\n\
| Sup || Wrap selected text with superscript tags (appearing half a character above the baseline).\n\
| Sub || Wrap selected text with subscript tags (appearing half a character below the baseline).\n\
| Left || Wrap selected text with a left-aligned div.\n\
| Center || Wrap selected text with a center-aligned div.\n\
| Right || Wrap selected text with a right-aligned div.\n\
| Justify || Wrap selected text with a justified div.\n\
| List || Add unordered list tags around the selected text.\n\
| List = || Add ordered list tags around the selected text.\n\
| li[*] || Wrap selected text with list item tags.\n\
| Blockquote || Wrap selected text with blockquote tags, indenting it beneath the current line.\n\
| Image || Include an external image.\n\
| Link || Include an external link URL.\n\
|}',
'= Edit a page\n\
All user-created pages (and some which are part of reserved [[WoaS::Help::Namespaces|namespaces]]) can be edited.\n\
\n\
If a page is editable the relative Edit icon will be available in the navigation bar; you start editing the page by clicking such icon. The user interface will switch to an [[Woas::Help::Editor|editor-mode set of buttons and edit areas]].\n\
\n\
== Editing\n\
\n\
In order to edit pages, click the *Edit* icon in the navigation bar. You can find all the user pages by accessing [[Special::All Pages]] directly or either from [[Special::Advanced]].\n\
# Click the *Edit* icon in the navigation bar or double-click on the page if you\'ve enabled that setting in the wiki Options.\x3Cbr\x3E\x3Cbr\x3E\n\
# Edit the contents of the main text area by typing normally.\x3Cbr\x3E\x3Cbr\x3E\n\
# Use the editor\'s buttons to insert code to format the text, or type the code in manually. Note that the use of plain text doesn\'t require any code.\x3Cbr\x3E\x3Cbr\x3E\n\
# Save your changes by clicking on the *Save* icon in the navigation bar.\n\
\n\
== Deleting\n\
See [[WoaS::Help::Delete a page]].',
'= Erase all pages\n\
To erase all user-created pages in this wiki and start fresh:\n\
# Access [[Special::Erase Wiki]] directly or either from [[Special::Advanced]]\n\
[[Include::WoaS::Template::Info|Make sure you are using a wiki you don\'t mind losing. If not, make a copy and erase the copy.]]\n\
See also the [[WoaS::Help::Special::Erase Wiki]] page.\n\
',
'= Edit the menu\n\
# Click the \x3Cspan class="woas_menu_button" style="font-size: medium"\x3EEdit menu\x3C/span\x3E button at the bottom of the menu\n\
# Edit the contents of the main text area; the menu page is like a normal wiki page\n\
# Save your changes by clicking on the *Save* icon in the top right navigation panel\n\
\n\
You can use various styles for your menu. A detailed explanation of list styles can be found in the [[WoaS::Help::Lists]] page.\n\
\n\
== Add a sub-menu beneath the menu\n\
See the *Namespace sub-menu* section of the [[WoaS::Help::Namespaces]] page.\n\
',
'= Headers\n\
Below are examples on how to use wiki markup to create headers in this wiki. There are six levels of supported headers.\n\
\n\
{{{\n\
= Header level 1\n\
}}}\n\
= Header level 1 =\n\
\n\
{{{\n\
== Header level 2\n\
}}}\n\
== Header level 2\n\
\n\
{{{\n\
== Header level 3\n\
}}}\n\
== Header level 3\n\
\n\
{{{\n\
== Header level 4\n\
}}}\n\
== Header level 4\n\
\n\
{{{\n\
== Header level 5\n\
}}}\n\
== Header level 5\n\
\n\
{{{\n\
== Header level 6\n\
}}}\n\
== Header level 6\n\
',
'= Rulers \n\
Rulers (horizontal rules or lines) use the full width of the page by default. They can be styled to a smaller width by surrounding them with HTML &lt;div&gt; tags. Styling can also control their position.\n\
\n\
== Standard ruler\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
----\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\x3Cbr\x3E\n\
----\n\
\n\
\n\
== Custom width ruler aligned left\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing 50% with the width you like:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Cdiv style="width:50%";\x3E\n\
----\n\
\x3C/div\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Cdiv style="width:50%";\x3E\n\
----\n\
\x3C/div\x3E\n\
\n\
== Custom width ruler aligned right\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing 50% with the width you like:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Cdiv style="width:50%; float:right;"\x3E\x3Chr\x3E\x3C/div\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Cdiv style="width:50%; float:right;"\x3E\x3Chr\x3E\x3C/div\x3E\n\
\n\
== Custom width centered ruler\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing 50% with the width you like:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Ccenter\x3E\x3Cdiv style="width:50%";\x3E\n\
----\n\
\x3C/div\x3E\x3C/center\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Ccenter\x3E\x3Cdiv style="width:50%";\x3E\n\
----\n\
\x3C/div\x3E\x3C/center\x3E\n\
',
'= Include text file\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing PATH with the full path to the file:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Ciframe height="400" width="100%" src="file:///PATH"\x3E\x3C/iframe\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo include a text file in the page inside an iFrame.\x3C/div\x3E\n\
* *Linux example:*\x3Cbr\x3E\x3Cbr\x3E{{{\n\
\x3Ciframe height="400" width="100%" src="file:///home/username/Desktop/file.txt"\x3E\x3C/iframe\x3E\n\
}}}\x3Cbr\x3E\n\
* *Windows example:*\x3Cbr\x3E\x3Cbr\x3E{{{\n\
\x3Ciframe height="400" width="100%" src="file:///C:/Users/Username/Documents/file.txt"\x3E\x3C/iframe\x3E\n\
}}}\n\
',
'= Include web page\n\
Web pages can be included in a page as embedded objects or in iFrames.\n\
\n\
[[Include::WoaS::Template::Info|Some pages may not render correctly depending on how they\'re coded. Embedding more than one web page in a wiki page will cause the final embedded web page to steal the focus when the page is loaded, so it\'s recommended to have only one per page.]]\n\
== Embed a web page as an object\n\
This method makes the embedded web page become a seamless part of the page.\n\
\n\
* *Embed a local HTML file as an object:*\x3Cbr\x3E\x3Cbr\x3E\n\
** \x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing PATH with the full path to the HTML file you wish to include, and changing the width and height to suit your taste:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Cobject data="PATH" style="width:100%; height:630px;"\x3EFile not found.\x3C/object\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo embed a local HTML file in a page.\x3C/div\x3E\x3Cbr\x3E\n\
*** For example, if you want to embed the {{{/Work/MyProject.html}}} file as an object, you\'d use this command:\x3Cbr\x3E\x3Cbr\x3E{{{\n\
\x3Cobject data="/Work/MyProject.html" style="width:100%; height:630px;"\x3EFile not found.\x3C/object\x3E\n\
}}}\x3Cbr\x3E\x3Cbr\x3E\n\
* *Embed a remote URL as an object:*\x3Cbr\x3E\x3Cbr\x3E\n\
** \x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing URL with the URL of the page you wish to include, and changing the width and height to suit your taste:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Cobject data="URL" style="width:100%; height:630px;"\x3EURL not found.\x3C/object\x3E\x3C\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo embed an external URL in a page.\x3C/div\x3E\x3Cbr\x3E\n\
*** For example, if you want to embed the WoaS official website at {{{http://stickwiki.sf.net/}}} as an object, you\'d use this command:\x3Cbr\x3E\x3Cbr\x3E{{{\n\
\x3Cobject data="http://stickwiki.sf.net/" style="width:100%; height:630px;"\x3EURL not found.\x3C/object\x3E\n\
}}}\n\
\n\
== Embed a web page in an iFrame\n\
This method creates a frame around the embedded web page. The code shown below is for a plain frame, but you can style the iFrame further by adding a border, changing the border style to dotted, dashed, solid, double, groove, ridge, inset, or outset, changing the border width to whatever thickness you like, and the border color to whatever color you like.\n\
\n\
* *Embed a local HTML file in an iFrame:*\x3Cbr\x3E\x3Cbr\x3E\n\
** \x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing PATH with the full path to HTML file you wish to include, and changing the width and height to suit your taste:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Ciframe height="400" width="100%" height:630px; src="PATH"\x3E\x3C/iframe\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo include a local HTML file in a wiki page.\x3C/div\x3E\x3Cbr\x3E\n\
*** For example, if you want to embed the {{{/Work/MyProject.html}}} file in an iFrame, you\'d use this command:\x3Cbr\x3E\x3Cbr\x3E{{{\n\
\x3Ciframe height="400" width="100%" height:630px; src="/Work/MyProject.html"\x3E\x3C/iframe\x3E\n\
}}}\x3Cbr\x3E\x3Cbr\x3E\n\
* *Embed a remote URL in an iFrame:*\x3Cbr\x3E\x3Cbr\x3E\n\
** \x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing URL with the URL of the page you wish to include, and changing the width and height to suit your taste:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Ciframe height="400" width="100%" height:630px; src="URL"\x3E\x3C/iframe\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo include a web page in a wiki page.\x3C/div\x3E\x3Cbr\x3E\n\
*** For example, if you want to embed the WoaS official website at {{{http://stickwiki.sf.net/}}} in an iFrame, you\'d use this command:\x3Cbr\x3E\x3Cbr\x3E{{{\n\
\x3Ciframe height="400" width="100%" height:630px; src="http://stickwiki.sf.net/"\x3E\x3C/iframe\x3E\n\
}}}\n\
',
'= Include wiki page\n\
To include the contents of a wiki page inside another wiki page, use an {{{[[Include::]]}}} tag on a line by itself, inserting the name of the page you\'d like to include after the double colons in the tag.\n\
\n\
[[Include::WoaS::Template::Info|Page names are case sensitive.]]\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing Page Name with the name of the page you wish to include:\x3C/div\x3E\n\
\x3Cdiv class="woas_helpcode"\x3E[\x3C!-- --\x3E[Include::Page Name]]\x3C/div\x3E\n\
\x3Cdiv class="woas_helptext"\x3ETo include the contents of another wiki page in the current page.\x3C/div\x3E\n\
\n\
== Example\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\n\
\x3Cdiv class="woas_helpcode"\x3E[\x3C!-- --\x3E[Include::Special::Search]\x3C!-- --\x3E]\x3C/div\x3E\n\
\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
[[Include::Special::Search]]\n\
',
'= JavaScript\n\
== Adding JavaScript to your page\n\
To add JavaScript to your page, you must enclose it inside JavaScript tags.\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing YOUR_CODE_HERE with your JavaScript code:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Cscript type="text/javascript"\x3E\n\
YOUR_CODE_HERE\n\
\x3C/script\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo add JavaScript to your page.\x3C/div\x3E\n\
== Adding JavaScript to the wiki source\n\
It is possible to add &lt;script/&gt; tags to your wiki source and they will be correctly rendered in the document &lt;head/&gt; tag upon page loading; also external scripts (using the /src/ attribute) will be parsed and activated, always respecting the order of declaration of the &lt;script /&gt; tags.\n\
\n\
[[Include::WoaS::Template::Info|Since the JavaScript tags are activated from within the &lt;head /&gt; tag, you cannot use document.write() or similar inline JavaScript statements.]]\n\
== Using external JavaScript\n\
You can include external JavaScript on a page by placing the script file in the same directory as this wiki and then inserting a reference to it in the body of the page.\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing SCRIPTNAME.JS with the name of your script:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Cscript src="SCRIPTNAME.JS"\x3E\x3C/script\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo include an external JavaScript in a page.\x3C/div\x3E\n\
=== Example\n\
This page contains this code:\x3Cbr\x3E\x3Cbr\x3E{{{\n\
\x3Cscript src="example.js"\x3E\x3C/script\x3E\n\
}}}\n\
To see an example using external JavaScript:\n\
# Create a text file in the same directory as this wiki.\x3Cbr\x3E\x3Cbr\x3E\n\
# Paste this into the file:\x3Cbr\x3E\x3Cbr\x3E{{{\n\
alert("This is an example alert!");\n\
}}}\x3Cbr\x3E\n\
# Save the file as *example.js*\x3Cbr\x3E\x3Cbr\x3E\n\
# Reload the wiki.\x3Cbr\x3E\x3Cbr\x3E\n\
# Open this page from the menu (not in the help pop-up) to run the *example.js* script and see the alert.\n\
\n\
== Using JavaScript to create a temporary page\n\
Using this code, you can get this wiki to create a link to a dynamically created temporary page with custom content (it accepts HTML tags as part of the content) under the JavaScript namespace. The temporary page will be created each time the link is clicked and uncreated as soon as you navigate to another page or close the wiki.\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing CONTENT with your content, NAME with the page name, and LINK with the text you want the link to have:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Cscript type="text/javascript"\x3Efunction temporary(arg) {return \'CONTENT\';}\x3C/script\x3E[[Javascript::temporary(\'NAME\')|LINK]]\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create a dynamically created temporary page.\x3C/div\x3E\n\
[[Include::WoaS::Template::Info|Only one of these links may be used per page.]]\n\
Paste each of these into a new page one by one to see what they do:\n\
* This one uses the temporary page name as part of its content:\x3Cbr\x3E\x3Cbr\x3E{{{\n\
\x3Cscript type="text/javascript"\x3Efunction temporary(arg) {return \'This page was dynamically created using *\'+arg+\'* as content!\';}\x3C/script\x3E[[Javascript::temporary(\'sample\')|Click here]]\n\
}}}\x3Cbr\x3E\n\
* This one demonstrates the use of various HTML tags in the content of the page:\x3Cbr\x3E\x3Cbr\x3E{{{\n\
\x3Cscript type="text/javascript"\x3Efunction temporary(arg) {return \'This page contains more than one line.\x3Cbr\x3EThis line contains \x3Cb\x3Ebold\x3C/b\x3E, \x3Ci\x3Eitalic\x3C/i\x3E, \x3Cu\x3Eunderlined\x3C/u\x3E, and \x3Cfont color="red"\x3Ecolored\x3C/font\x3E text.\x3Cbr\x3E\x3Cbr\x3EAnd here is a list:\x3Cbr\x3E\x3Cul\x3E\x3Cli\x3Eitem1\x3C/li\x3E\x3Cli\x3Eitem2\x3C/li\x3E\x3Cli\x3Eitem3\x3C/li\x3E\x3C/ul\x3E\';}\x3C/script\x3E[[Javascript::temporary(\'My Page\')|Click here]]\n\
}}}\n\
\n\
== Using JavaScript to reload the wiki\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Cinput type="button" value="Reload wiki" onclick="window.location.href=window.location.href"\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create a button that reloads the wiki when you click it.\x3C/div\x3E\n\
',
'= Join lines of text\n\
Lengthy wiki page content can be broken up into shorter lines in the editor (while still being parsed as a single line when the page is viewed) by using a backslash at the *end* of any line; such a line will be joined with the one below it.\n\
\n\
[[Include::WoaS::Template::Info|Backslashes *within* a line will be ignored by the wiki parser and will not influence how the text is displayed.]]\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
Putting a \\ at the end of any line \\\n\
makes it join together \\\n\
with the line below it.\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
Putting a \\ at the end of any line \\\n\
makes it join together \\\n\
with the line below it.\n\
',
'= Namespaces\n\
When you create a page with double colons (*::*) as a separator in the page name, you are using a namespace to define parent and child pages. Sub-namespaces are created by adding more than one *::* separator to the page name. Each namespace or sub-namespace can have as many child pages under it as you like (within the resource limits of your hardware). The full path to each page is displayed in the navigation bar with links to its namespace and sub-namespace(s) in the title.\n\
\n\
For example, let\'s say you have these pages:\n\
* {{{[[Recipes::Desserts]]}}}\n\
* {{{[[Recipes::Desserts::Cakes]]}}}\n\
* {{{[[Recipes::Main dishes]]}}}\n\
* {{{[[Recipes::Side dishes]]}}}\n\
* {{{[[Recipes::Soups]]}}}\n\
\n\
*Recipes::* is a namespace. *Desserts::* is a sub-namespace of the *Recipes::* namespace. *Cakes::* is a sub-namespace of the *Desserts::* sub-namespace.\n\
\n\
If you open the {{{[[Recipes::Desserts::Cakes]]}}} page, the title contains links to *Recipes* and *Desserts*. The *Recipes* link opens a page listing all pages in the *Recipes::* namespace, and the *Desserts* link opens a page listing all pages in the *Desserts::* sub-namespace.\n\
\n\
=== Namespace sub-menu\n\
All pages in any namespace can be given a custom sub-menu by creating a *::Menu* page inside the namespace. A sub-menu will be temporarily added to the main menu when any pages belonging to that page\'s namespace are opened. You can determine what goes into the sub-menu by editing the page with *::Menu* in its name. The sub-menu will vanish as soon as you navigate away from its namespace.\n\
\n\
For example, if you create the {{{[[Recipes::Menu]]}}} page with *My favorite recipes!* as its content, then whenever you open a page in the {{{Recipes::}}} namespace, a sub-menu will appear with *My favorite recipes!* in it.\n\
\n\
\x3Cdiv style="background-color: #FFFFAA; border: 0.1em solid; padding: 0.2em;"\x3E\x3Cimg src="%2FAAAAAAABAQEBAQECAgICAwMDBAQFBQUABgYGCQgJCgoLDAsMDQwPDQ0NDw4PDw8HEhETExMUFRQUGRkNGhsUGxscHx8eISATIR8lJCQVJiUsJyUqKCcuLCwtLiw0Ly4vMzE4NzYoQT9FQz9ERkZGSkdTS0hMTEhNUk5bU1JVY15kYWBkZWFubGh5bmt1cGt6c212cm5%2BcXFwfHaDfXxehoKQjIiUkYyfkoyllZKal5CpmJGqmJGrmZKtmpaim5WunJaunZewn5mxoJqyopquoZuxpJylopyyopy1pJ22pJ24pJ61pJ%2B1paC1pqC1qaC0pqG1qKG7qqKuqaKxqKK4paWkq6O7qaS3q6p%2BraW4rae6rKmvrqm1rqm6r6nDsKu1sKu9sKu%2Bs6yxs7GDsay9sq29s667tK7FuK%2FBtbDAtbDBt7HEubS%2BubTCurTKurXFvLqjvLfGvLjEv72LvL2VvbjLvr%2BPwL%2BKvbvBw7nHv7vDwMGHw7rHwb3Fwr3Lw8SQxb%2FRxsDRxsHMxcLGxsPLyMPQx8XKyMXIysuOycbIzMfVzcrMz8zU0NGi0czZ0M%2FL0c%2FL0c%2FN0s7X08%2FZ1NPN1ten1tTR1tXP19XS2tfc3Nyt3N2s3dni397W4N%2FX4N%2FZ4t7m4eDY4t%2Fm4eHY4uHb4uDl4uLX4%2BLa5OLo5OTb5ubd6OjJ6Ofh6erE6efr6efs6ujs6%2Bju6%2B3B6%2Brj6%2Bnt6%2Brl7O6%2F6%2Bvk7Ovr7Ovu7evu7vDC7ezv7e3p7u7p7%2B7w7%2B7x7%2B%2Fx8fPF8PDt8e%2F18fDs8fDy8fDz8%2FXC8fHx8%2FD38vLt8vLu8vL08%2FPt8%2FPu9PP09vjI9fXw9vX09vbx9%2FX59%2Fby9%2Fb39%2Ffx%2BPf4%2Bfj5%2Bfj6%2Bfnz%2Bfn1%2Bfr1%2B%2F7K%2Bvr2%2B%2Fr5%2FPr%2F%2B%2Fv7%2FP%2FR%2Ffv%2B%2Ffz9%2F%2F7%2FFnlyNwAAAAF0Uk5TAEDm2GYAAAABYktHRACIBR1IAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH2gMHDxg0DfX8UQAAAUBJREFUKM9jYCAIGBl5hLgYGTGEuXViWpvTzZVZUaUYFdofXzu4YW53o5kgsgyj3LIXFy8e2rphclaZBS%2BSDHvlsxvPb5%2FbtXFKQVyGHkKCUev08TtPbp3Yu7KtKMnfUxIuw2h19MCVu9dP7Z41c3qeR5AmXII1YdOuy%2Ffv3dyyZMfqLhdvA7gEZ%2BzC9UcePrp6%2Fuz%2B%2BdWOXiYIo%2Bz7F%2B%2B8cGb5qkUz6vxsww0REvpN9b3zjq3oKU7zcbLOVEdIyOSkZk%2FatrYj1NfZNiCYH8mDuvmB1Qv2TYxwsHGt0kDyICObUXz01KUT3OyiarVRAouJWc0ysSU3JNldBT18mYUL16ybXaHEiBkfNQ%2B290WKyGNKNFzaMy1FQhZTovzp4TklUtKYEp0nN5eaCihiSPBxiIapMopjSw5iLIzGhBMNAHCEbLFZHo5dAAAAAElFTkSuQmCC" alt="Info" border="0" /\x3E Sub-menus work the same way menus do. For more information on menus, see the [[WoaS::Help::Edit the menu]] page.\x3C/div\x3E\n\
== Reserved namespaces\n\
Some namespaces are reserved by the wiki for its own internal use or for specific use by the user:\n\
* *File::* for embedded files\n\
* *Image::* for embedded images\n\
* *Include::* for transclusion\n\
* *Javascript::* for direct JavaScript execution\n\
* *Lock::* used internally for encrypted pages\n\
* *Locked::* for encrypted pages\n\
* *::Menu* for sub-menus\n\
* *Special::* for all the special pages\n\
* *Tagged::* for all the tagged pages\n\
* *Tag::* for tagging pages\n\
* *Unlock::* used internally for encrypted pages\n\
* *Unlocked::* for plain (unencrypted) pages\n\
* *WoaS::* for core WoaS pages\n\
',
'= Text formatting\n\
== Bold\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
*This is bold text.*\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
*This is bold text.*\n\
\n\
== Colored\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Cspan style="color:#FF00FF"\x3EThis is colored text.\x3C/span\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Cspan style="color:#FF00FF"\x3EThis is colored text.\x3C/span\x3E\n\
\n\
\x3Cdiv class="woas_helptext"\x3EOr use this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Cspan style="color:fuchsia"\x3EThis is colored text.\x3C/span\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Cspan style="color:fuchsia"\x3EThis is colored text.\x3C/span\x3E\n\
\n\
== Italic\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
/This is italic text./\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
/This is italic text./\n\
\n\
== Plain\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
This is plain text.\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
This is plain text.\n\
\n\
== Underlined\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
_This is underlined text._\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
_This is underlined text._\n\
\n\
== Underlined Bold Italic\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
_*/This is underlined and bold and italic text./*_\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
_*/This is underlined and bold and italic text./*_\n\
',
'= Rename a page\n\
# Click the *Edit* icon in the navigation bar.\n\
# Edit the contents of the text inside the *Page title* area at the top of the page.\n\
# Save your changes by clicking on the *Save* icon in the navigation bar.\n\
\n\
= Reference links\n\
Renaming a page will automatically rename also the references to such page in other pages.',
'= Page scrolling\n\
By default, this wiki offers two choices for scrolling. You can change these settings by clicking the *Advanced* icon in the navigation bar and then clicking the {{{[[Special::Options]]}}} link.\n\
\n\
The *Fixed menu area and navigation bar* option can be enabled and disabled by placing a check mark in the box next to the option. Enabling it locks the navigation bar and menu in place while allowing the rest of the page to scroll. Disabling it allows the entire page to scroll as one connected unit.\n\
',
'= Table of Contents\n\
You can insert a Table of Contents into your page by using a special wiki tag. It will be automatically populated with all the headers on a page. The placement of the Table of Contents is  determined by where you put the tag in the page.\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code on a line by itself in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
[[Special::TOC]]\n\
}}}\n\
\x3Cdiv class="woas_helptext"\x3ETo add a Table of Contents to the page.\x3C/div\x3E\n\
\n\
[[Include::WoaS::Template::Info|The Table of Contents expects the first header on a page to be a Level 1 header. If you use any other level header first, that header and any headers after it will be represented by hash marks until a Level 1 header is encountered. From that point on, the headers will be numbered properly.]]\n\
== Example\n\
Create a page with these contents:\x3Cbr\x3E\x3Cbr\x3E{{{\n\
[[Special::TOC]]\n\
= My level one header\n\
== My level two header\n\
=== My level three header\n\
==== My level four header\n\
===== My level five header\n\
====== My level six header\n\
}}}\n\
When you save the page, there will be a Table of Contents that looks like this at the top of the page:\n\
\n\
\x3Cdiv style="border:1pt dashed #aaa; background-color:#f9f9f9; padding:0.313em; \n\
width:50%; font-size:95%;"\x3E\x3Ccenter\x3E\x3Cb\x3ETable of Contents\x3C/b\x3E\x3C/center\x3E\n\
&nbsp;&nbsp;&nbsp;1. \x3Cspan style="color:blue; text-decoration:underline;"\x3EMy level one header\x3C/span\x3E\n\
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. \x3Cspan style="color:blue; text-decoration:underline;"\x3EMy level two header\x3C/span\x3E\n\
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. \x3Cspan style="color:blue; text-decoration:underline;"\x3EMy level three header\x3C/span\x3E\n\
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. \x3Cspan style="color:blue; text-decoration:underline;"\x3EMy level four header\x3C/span\x3E\n\
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. \x3Cspan style="color:blue; text-decoration:underline;"\x3EMy level five header\x3C/span\x3E\n\
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. \x3Cspan style="color:blue; text-decoration:underline;"\x3EMy level six header\x3C/span\x3E\n\
\x3C/div\x3E\n\
',
'= Tags\n\
Tags are used to group pages by categories/features/topics so they can easily be found again.\n\
\n\
Tags can be placed anywhere on a page, but choosing a standard location like the bottom of the page makes them easier to find and edit as your wiki grows.\n\
\n\
Tag a page by using a {{{[[Tag::tag1]]}}} link, adding the tag name or names after the double colons; multiple tags should be separated with commas.\n\
\n\
You can also use the *Tag* button in the editor.\n\
\n\
=== Add a tag to a page (method 1)\n\
# Click the *Tags* button in the editor.\x3Cbr\x3E\x3Cbr\x3E\n\
# Type in a name for the tag.\x3Cbr\x3E\x3Cbr\x3E\n\
# Click the *OK* button.\n\
\n\
=== Add a tag to a page (method 2)\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing EXAMPLE with the name of the tag you\'d like to add:\x3C/div\x3E\n\
\x3Cdiv class="woas_helpcode"\x3E[\x3C!-- --\x3E[Tag::EXAMPLE]]\x3C/div\x3E\n\
\x3Cdiv class="woas_helptext"\x3ETo add a tag to your page.\x3C/div\x3E\n\
=== Add more than one tag to a page (method 1)\n\
# Click the *Tags* button in the editor.\x3Cbr\x3E\x3Cbr\x3E\n\
# Type in names for the tags, separating each from the one before it with a comma. For example:\x3Cbr\x3E\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing EXAMPLE1, EXAMPLE2, and EXAMPLE3 with the names of the tags you\'d like to add:\x3C/div\x3E\x3Cbr\x3E\x3Cdiv class="woas_helpcode"\x3E{{{[[Tag::EXAMPLE1, EXAMPLE2, EXAMPLE3]]}}}\x3C/div\x3E\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo add three tags to your page.\x3C/div\x3E\x3Cbr\x3E\n\
# Click the *OK* button.\n\
\n\
=== Add more than one tag to a page (method 2)\n\
To use more than one tag on a page, use one tag link and add as many tags as you like, separating each from the one before it with a comma. For example: {{{[[Tag::Recipes, Chocolate, Layered cakes]]}}}.\n\
\n\
=== Choosing tag names\n\
Tag names are case sensitive. For example: {{{[[Tag::Recipes]]}}} and {{{[[Tag::recipes]]}}} are two different tags.\n\
\n\
Tag names can be more than one word long with a space between each word. For example: {{{[[Tag::Layered cakes]]}}}.\n\
\n\
=== Add a link to tagged pages\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing EXAMPLE with the tag you\'d like to use:\x3C/div\x3E\n\
\x3Cdiv class="woas_helpcode"\x3E{{{[[Tagged::EXAMPLE]]}}}\x3C/div\x3E\n\
\x3Cdiv class="woas_helptext"\x3ETo create a listing of pages tagged with EXAMPLE.\x3C/div\x3E\n\
\n\
=== Add a filtered link to tagged pages\n\
By putting an exclamation mark (*!*) in front of the tag name, you can filter out a specific tag from a tagged pages list:\x3Cbr\x3E\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing EXAMPLE with the tag you\'d like to filter out:\x3C/div\x3E\n\
\x3Cdiv class="woas_helpcode"\x3E[\x3C!-- --\x3E[Tagged::!EXAMPLE]\x3C!-- --\x3E]\x3C/div\x3E\n\
\x3Cdiv class="woas_helptext"\x3ETo create a filtered listing of tagged pages that are not tagged with EXAMPLE.\x3C/div\x3E\n\
\n\
=== Include a listing of tagged pages\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing EXAMPLE with the tag you\'d like to use:\x3C/div\x3E\n\
\x3Cdiv class="woas_helpcode"\x3E[\x3C!-- --\x3E[Include::Tagged::EXAMPLE]\x3C!-- --\x3E]\x3C/div\x3E\n\
\x3Cdiv class="woas_helptext"\x3ETo display a listing of pages tagged with EXAMPLE inside the current page.\x3C/div\x3E\n\
\n\
=== Include a filtered listing of tagged pages\n\
By putting an exclamation mark (*!*) in front of the tag name, you can filter out a specific tag from a tagged pages list:\x3Cbr\x3E\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing EXAMPLE with the tag you\'d like to filter out:\x3C/div\x3E\n\
\x3Cdiv class="woas_helpcode"\x3E[\x3C!-- --\x3E[Include::Tagged::!EXAMPLE]\x3C!-- --\x3E]\x3C/div\x3E\n\
\x3Cdiv class="woas_helptext"\x3ETo display a filtered listing of tagged pages that are not tagged with EXAMPLE inside the current page.\x3C/div\x3E\n\
',
'= Publish wiki online\n\
This wiki can be published online as a single-file, framed web page by making it read-only. The read-only format can also be used for sharing your work with others by email. Most email programs accept .html pages as attachments.\n\
# Make a backup copy of this wiki.\n\
# Click the *Advanced* icon in the navigation bar.\n\
# Scroll to the bottom of the page.\n\
# Click the *Disallow edits* button to make the file read-only.\n\
# Upload the wiki to a web server and publish a link to it.\n\
To enable wiki editing again, see the [[WoaS::Help::Wiki is read-only]] page.\n\
',
'= Run wiki on a webserver\n\
Wiki on a Stick is a client software not designed to be used on a webserver; WoaS will anyway recognize that it is being run from a webserver and prevent save operations with an appropriate user message informing about the impossibility to save permanent changes.\n\
\n\
== Server integration\n\
\n\
WoaS 1.0 will offer an API to allow server-side integrations.',
'= Requirements =\n\
\n\
== Supported Browsers\n\
Wiki on a Stick is actively supported on the following browsers:\n\
\n\
* Firefox 1.5\n\
* Firefox 2\n\
* Firefox 3\n\
* Firefox 3.5+\n\
* Opera\n\
* Internet Explorer 6\n\
* Internet Explorer 7*\n\
* Internet Explorer 8*\n\
* Chrome\n\
* Safari\n\
\x3Cdiv class="alertnote"\x3E* On IE7 (and above) you might want to rename your application to .hta to enable its trusted privileges.\x3C/div\x3E\n\
== Limitations\n\
* Firefox (and possibly other browsers, too) cannot save to filenames containing UTF8 characters. Use unix-style filenames instead.\n\
* Internet Explorer 6 and 7 do not support embedded images (that\'s why you will not see button icons).\n\
* Internet Explorer does not allow saving to a network path in the form /\\\\machine\\share\\bookonastick.htm/. To use this wiki over a network with Internet Explorer, map network paths to network drives first.\n\
* Internet Explorer 6 does not allow a fixed menu.\n\
\n\
If you are using Chrome, Safari or Opera you will need the TiddlySaver Java applet, hence you need that Java is enabled in your browser and that it properly works.\n\
\n\
== TiddlySaver\n\
\n\
The Java applet "TiddlySaver.jar", a very small file, must be placed in the same directory as your WoaS file. In order to use it you will need to give it the necessary privileges by editing your .java.policy file.\n\
\n\
For Windows, the file will be at C:\\Documents and Settings\\your-user-name\\.java.policy. Add the following lines (substituting the directory  as appropriate):\n\
\n\
{{{\n\
grant codeBase "file:${user.home}/My Documents/tiddlywiki-folder/*" {\n\
  permission java.io.FilePermission "${user.home}${/}My Documents${/}stickwiki-folder${/}*", "read,write";\n\
};\n\
}}}\n\
On Mac OS X, the file is found at {{{/Users/your-user-name/.java.policy}}}:\n\
\n\
{{{\n\
grant codeBase "file:${user.home}/Documents/tiddlywiki-folder/*" {\n\
  permission java.io.FilePermission "${user.home}${/}Documents${/}stickwiki-folder${/}*", "read,write";\n\
};\n\
}}}\n\
It can be tricky creating files whose name starts with a period, so you can use this [[https://stickwiki.svn.sourceforge.net/svnroot/stickwiki/trunk/woas/.java.policy|pre-built .java.policy file]]. The same file is suitable for Macs too, just edit it and delete the "My " bit, leaving just "Documents". Make sure you save it in the right place for each operating system!\n\
\n\
If you have trouble setting up the permissions correctly, you can try granting broader permissions to the applet like this:\n\
\n\
{{{\n\
grant codeBase "file://localhost/home/users/Desktop/\n\
TiddlySaver.jar"\n\
 { permission java.security.AllPermission; };\n\
}}}\n\
The TiddlySaver java applet was written by J.Rouston.\n\
',
'= Lists\n\
Simple single-level lists can be created by using the list buttons in the editor.\n\
* The *{{{*}}}* button inserts the wiki syntax for a bulleted list item\n\
* The *{{{#}}}* button inserts the wiki syntax for a numbered list item.\n\
* The *{{{@}}}* button inserts the wiki syntax for an alphanumeric list item.\n\
* The *{{{List}}}* button wraps HTML ul tags around the selected text to create an unordered list.\n\
* The *{{{List =}}}* button wraps HTML ol tags around the selected text to create an ordered list.\n\
* The *{{{li[*]}}}* button wraps HTML li tags around the selected text to create a list item.\n\
If you\'d like to create mixed lists, nested lists, or lists with additional types of list items, the methods below can be used instead.\n\
\n\
== Wiki markup lists\n\
Wiki markup lists are created with between one and five specific characters ({{{@}}}, {{{*}}}, or {{{#}}}) at the beginning of a line, followed by a space, and then whatever text you\'d like the list item to have. Each list must begin with a list item with only one character at the beginning of the line, and there can be no blank lines between entries in the list. To create a blank line beneath a list item, you can insert two HTML {{{\x3Cbr\x3E}}} tags at the end of of the list item\'s text. Wiki and HTML markup are accepted in list items.\n\
\n\
=== Alphanumeric List\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
@ Test\n\
@ Test\n\
@ Test\n\
@@ Test\n\
@@@ Test\n\
@@@@ Test\n\
@ Test\n\
@ Test\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
@ Test\n\
@ Test\n\
@ Test\n\
@@ Test\n\
@@@ Test\n\
@@@@ Test\n\
@ Test\n\
@ Test\n\
\n\
=== Bulleted List\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
* Test\n\
* Test\n\
** Test\n\
*** Test\n\
**** Test\n\
* Test\n\
* Test\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\x3Cbr\x3E\n\
* Test\n\
* Test\n\
** Test\n\
*** Test\n\
**** Test\n\
* Test\n\
* Test\n\
\n\
=== Fancy List\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
* ITEM 1 - ITEM 1 SUBTEXT \x3Cblockquote\x3EITEM 1 MORE SUBTEXT\x3C/blockquote\x3E\n\
* ITEM 2 - ITEM 2 SUBTEXT \x3Cblockquote\x3EITEM 2 MORE SUBTEXT\x3C/blockquote\x3E\n\
* ITEM 3 - ITEM 3 SUBTEXT \x3Cblockquote\x3EITEM 3 MORE SUBTEXT\x3C/blockquote\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\x3Cbr\x3E\n\
* ITEM 1 - ITEM 1 SUBTEXT \x3Cblockquote\x3EITEM 1 MORE SUBTEXT\x3C/blockquote\x3E\n\
* ITEM 2 - ITEM 2 SUBTEXT \x3Cblockquote\x3EITEM 2 MORE SUBTEXT\x3C/blockquote\x3E\n\
* ITEM 3 - ITEM 3 SUBTEXT \x3Cblockquote\x3EITEM 3 MORE SUBTEXT\x3C/blockquote\x3E\n\
\n\
=== Numbered List\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
# Test\n\
# Test\n\
## Test\n\
### Test\n\
#### Test\n\
# Test\n\
# Test\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\x3Cbr\x3E\n\
# Test\n\
# Test\n\
## Test\n\
### Test\n\
#### Test\n\
# Test\n\
# Test\n\
\n\
=== Numbered Fancy List\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
# ITEM 1 - ITEM 1 SUBTEXT \x3Cblockquote\x3EITEM 1 MORE SUBTEXT\x3C/blockquote\x3E\n\
# ITEM 2 - ITEM 2 SUBTEXT \x3Cblockquote\x3EITEM 2 MORE SUBTEXT\x3C/blockquote\x3E\n\
# ITEM 3 - ITEM 3 SUBTEXT \x3Cblockquote\x3EITEM 3 MORE SUBTEXT\x3C/blockquote\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\x3Cbr\x3E\n\
# ITEM 1 - ITEM 1 SUBTEXT \x3Cblockquote\x3EITEM 1 MORE SUBTEXT\x3C/blockquote\x3E\n\
# ITEM 2 - ITEM 2 SUBTEXT \x3Cblockquote\x3EITEM 2 MORE SUBTEXT\x3C/blockquote\x3E\n\
# ITEM 3 - ITEM 3 SUBTEXT \x3Cblockquote\x3EITEM 3 MORE SUBTEXT\x3C/blockquote\x3E\n\
\n\
== HTML Lists\n\
HTML lists work the same way as they do in any web page. Specifying the list type can be done in the {{{\x3Col\x3E}}}, {{{\x3Cul\x3E}}}, or {{{\x3Cli\x3E}}} tags, depending on how you need to use them. Wiki markup is accepted in list items.\n\
\n\
=== Specifying list type in the &lt;ol&gt; tag\n\
This method is useful when an entire list will use one list item type. This way you only need to specify the type once, and all the list items can be entered normally.\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Col style="list-style-type:lower-alpha;"\x3E\n\
\x3Cli\x3Elower-alpha\x3C/li\x3E\n\
\x3Cli\x3Elower-alpha\x3C/li\x3E\n\
\x3Cli\x3Elower-alpha\x3C/li\x3E\n\
\x3C/ol\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Col style="list-style-type:lower-alpha;"\x3E\n\
\x3Cli\x3Elower-alpha\x3C/li\x3E\n\
\x3Cli\x3Elower-alpha\x3C/li\x3E\n\
\x3Cli\x3Elower-alpha\x3C/li\x3E\n\
\x3C/ol\x3E\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Col style="list-style-type:upper-alpha;"\x3E\n\
\x3Cli\x3Eupper-alpha\x3C/li\x3E\n\
\x3Cli\x3Eupper-alpha\x3C/li\x3E\n\
\x3Cli\x3Eupper-alpha\x3C/li\x3E\n\
\x3C/ol\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Col style="list-style-type:upper-alpha;"\x3E\n\
\x3Cli\x3Eupper-alpha\x3C/li\x3E\n\
\x3Cli\x3Eupper-alpha\x3C/li\x3E\n\
\x3Cli\x3Eupper-alpha\x3C/li\x3E\n\
\x3C/ol\x3E\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Col style="list-style-type:decimal;"\x3E\n\
\x3Cli\x3Edecimal\x3C/li\x3E\n\
\x3Cli\x3Edecimal\x3C/li\x3E\n\
\x3Cli\x3Edecimal\x3C/li\x3E\n\
\x3C/ol\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Col style="list-style-type:decimal;"\x3E\n\
\x3Cli\x3Edecimal\x3C/li\x3E\n\
\x3Cli\x3Edecimal\x3C/li\x3E\n\
\x3Cli\x3Edecimal\x3C/li\x3E\n\
\x3C/ol\x3E\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Col style="list-style-type:lower-roman;"\x3E\n\
\x3Cli\x3Elower-roman\x3C/li\x3E\n\
\x3Cli\x3Elower-roman\x3C/li\x3E\n\
\x3Cli\x3Elower-roman\x3C/li\x3E\n\
\x3C/ol\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Col style="list-style-type:lower-roman;"\x3E\n\
\x3Cli\x3Elower-roman\x3C/li\x3E\n\
\x3Cli\x3Elower-roman\x3C/li\x3E\n\
\x3Cli\x3Elower-roman\x3C/li\x3E\n\
\x3C/ol\x3E\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Col style="list-style-type:upper-roman;"\x3E\n\
\x3Cli\x3Eupper-roman\x3C/li\x3E\n\
\x3Cli\x3Eupper-roman\x3C/li\x3E\n\
\x3Cli\x3Eupper-roman\x3C/li\x3E\n\
\x3C/ol\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Col style="list-style-type:upper-roman;"\x3E\n\
\x3Cli\x3Eupper-roman\x3C/li\x3E\n\
\x3Cli\x3Eupper-roman\x3C/li\x3E\n\
\x3Cli\x3Eupper-roman\x3C/li\x3E\n\
\x3C/ol\x3E\n\
\n\
=== Specifying list type in the &lt;ul&gt; tag\n\
This method is useful when an entire list will use one list item type. This way you only need to specify the type once, and all the list items can be entered normally.\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Cul style="list-style-type:circle;"\x3E\n\
\x3Cli\x3Ecircle\x3C/li\x3E\n\
\x3Cli\x3Ecircle\x3C/li\x3E\n\
\x3Cli\x3Ecircle\x3C/li\x3E\n\
\x3C/ul\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Cul style="list-style-type:circle;"\x3E\n\
\x3Cli\x3Ecircle\x3C/li\x3E\n\
\x3Cli\x3Ecircle\x3C/li\x3E\n\
\x3Cli\x3Ecircle\x3C/li\x3E\n\
\x3C/ul\x3E\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Cul style="list-style-type:disc;"\x3E\n\
\x3Cli\x3Edisc\x3C/li\x3E\n\
\x3Cli\x3Edisc\x3C/li\x3E\n\
\x3Cli\x3Edisc\x3C/li\x3E\n\
\x3C/ul\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Cul style="list-style-type:disc;"\x3E\n\
\x3Cli\x3Edisc\x3C/li\x3E\n\
\x3Cli\x3Edisc\x3C/li\x3E\n\
\x3Cli\x3Edisc\x3C/li\x3E\n\
\x3C/ul\x3E\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Cul style="list-style-type:none;"\x3E\n\
\x3Cli\x3Enone\x3C/li\x3E\n\
\x3Cli\x3Enone\x3C/li\x3E\n\
\x3Cli\x3Enone\x3C/li\x3E\n\
\x3C/ul\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Cul style="list-style-type:none;"\x3E\n\
\x3Cli\x3Enone\x3C/li\x3E\n\
\x3Cli\x3Enone\x3C/li\x3E\n\
\x3Cli\x3Enone\x3C/li\x3E\n\
\x3C/ul\x3E\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Cul style="list-style-type:square;"\x3E\n\
\x3Cli\x3Esquare\x3C/li\x3E\n\
\x3Cli\x3Esquare\x3C/li\x3E\n\
\x3Cli\x3Esquare\x3C/li\x3E\n\
\x3C/ul\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Cul style="list-style-type:square;"\x3E\n\
\x3Cli\x3Esquare\x3C/li\x3E\n\
\x3Cli\x3Esquare\x3C/li\x3E\n\
\x3Cli\x3Esquare\x3C/li\x3E\n\
\x3C/ul\x3E\n\
\n\
=== Specifying list type in the &lt;li&gt; tag\n\
This method is useful when creating a fancy list with more than one list item type.\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Col\x3E\n\
\x3Cli style="list-style-type:lower-alpha;"\x3Elower-alpha\x3C/li\x3E\n\
\x3Cli style="list-style-type:lower-alpha;"\x3Elower-alpha\x3C/li\x3E\n\
\x3Cli style="list-style-type:lower-alpha;"\x3Elower-alpha\x3C/li\x3E\n\
\x3C/ol\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Col\x3E\n\
\x3Cli style="list-style-type:lower-alpha;"\x3Elower-alpha\x3C/li\x3E\n\
\x3Cli style="list-style-type:lower-alpha;"\x3Elower-alpha\x3C/li\x3E\n\
\x3Cli style="list-style-type:lower-alpha;"\x3Elower-alpha\x3C/li\x3E\n\
\x3C/ol\x3E\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Col\x3E\n\
\x3Cli style="list-style-type:upper-alpha;"\x3Eupper-alpha\x3C/li\x3E\n\
\x3Cli style="list-style-type:upper-alpha;"\x3Eupper-alpha\x3C/li\x3E\n\
\x3Cli style="list-style-type:upper-alpha;"\x3Eupper-alpha\x3C/li\x3E\n\
\x3C/ol\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Col\x3E\n\
\x3Cli style="list-style-type:upper-alpha;"\x3Eupper-alpha\x3C/li\x3E\n\
\x3Cli style="list-style-type:upper-alpha;"\x3Eupper-alpha\x3C/li\x3E\n\
\x3Cli style="list-style-type:upper-alpha;"\x3Eupper-alpha\x3C/li\x3E\n\
\x3C/ol\x3E\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Col\x3E\n\
\x3Cli style="list-style-type:circle;"\x3Ecircle\x3C/li\x3E\n\
\x3Cli style="list-style-type:circle;"\x3Ecircle\x3C/li\x3E\n\
\x3Cli style="list-style-type:circle;"\x3Ecircle\x3C/li\x3E\n\
\x3C/ol\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Col\x3E\n\
\x3Cli style="list-style-type:circle;"\x3Ecircle\x3C/li\x3E\n\
\x3Cli style="list-style-type:circle;"\x3Ecircle\x3C/li\x3E\n\
\x3Cli style="list-style-type:circle;"\x3Ecircle\x3C/li\x3E\n\
\x3C/ol\x3E\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Col\x3E\n\
\x3Cli style="list-style-type:decimal;"\x3Edecimal\x3C/li\x3E\n\
\x3Cli style="list-style-type:decimal;"\x3Edecimal\x3C/li\x3E\n\
\x3Cli style="list-style-type:decimal;"\x3Edecimal\x3C/li\x3E\n\
\x3C/ol\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Col\x3E\n\
\x3Cli style="list-style-type:decimal;"\x3Edecimal\x3C/li\x3E\n\
\x3Cli style="list-style-type:decimal;"\x3Edecimal\x3C/li\x3E\n\
\x3Cli style="list-style-type:decimal;"\x3Edecimal\x3C/li\x3E\n\
\x3C/ol\x3E\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Col\x3E\n\
\x3Cli style="list-style-type:disc;"\x3Edisc\x3C/li\x3E\n\
\x3Cli style="list-style-type:disc;"\x3Edisc\x3C/li\x3E\n\
\x3Cli style="list-style-type:disc;"\x3Edisc\x3C/li\x3E\n\
\x3C/ol\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Col\x3E\n\
\x3Cli style="list-style-type:disc;"\x3Edisc\x3C/li\x3E\n\
\x3Cli style="list-style-type:disc;"\x3Edisc\x3C/li\x3E\n\
\x3Cli style="list-style-type:disc;"\x3Edisc\x3C/li\x3E\n\
\x3C/ol\x3E\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Col\x3E\n\
\x3Cli style="list-style-type:lower-roman;"\x3Elower-roman\x3C/li\x3E\n\
\x3Cli style="list-style-type:lower-roman;"\x3Elower-roman\x3C/li\x3E\n\
\x3Cli style="list-style-type:lower-roman;"\x3Elower-roman\x3C/li\x3E\n\
\x3C/ol\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Col\x3E\n\
\x3Cli style="list-style-type:lower-roman;"\x3Elower-roman\x3C/li\x3E\n\
\x3Cli style="list-style-type:lower-roman;"\x3Elower-roman\x3C/li\x3E\n\
\x3Cli style="list-style-type:lower-roman;"\x3Elower-roman\x3C/li\x3E\n\
\x3C/ol\x3E\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Col\x3E\n\
\x3Cli style="list-style-type:none;"\x3Enone\x3C/li\x3E\n\
\x3Cli style="list-style-type:none;"\x3Enone\x3C/li\x3E\n\
\x3Cli style="list-style-type:none;"\x3Enone\x3C/li\x3E\n\
\x3C/ol\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Col\x3E\n\
\x3Cli style="list-style-type:none;"\x3Enone\x3C/li\x3E\n\
\x3Cli style="list-style-type:none;"\x3Enone\x3C/li\x3E\n\
\x3Cli style="list-style-type:none;"\x3Enone\x3C/li\x3E\n\
\x3C/ol\x3E\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Col\x3E\n\
\x3Cli style="list-style-type:square;"\x3Esquare\x3C/li\x3E\n\
\x3Cli style="list-style-type:square;"\x3Esquare\x3C/li\x3E\n\
\x3Cli style="list-style-type:square;"\x3Esquare\x3C/li\x3E\n\
\x3C/ol\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Col\x3E\n\
\x3Cli style="list-style-type:square;"\x3Esquare\x3C/li\x3E\n\
\x3Cli style="list-style-type:square;"\x3Esquare\x3C/li\x3E\n\
\x3Cli style="list-style-type:square;"\x3Esquare\x3C/li\x3E\n\
\x3C/ol\x3E\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Col\x3E\n\
\x3Cli style="list-style-type:upper-roman;"\x3Eupper-roman\x3C/li\x3E\n\
\x3Cli style="list-style-type:upper-roman;"\x3Eupper-roman\x3C/li\x3E\n\
\x3Cli style="list-style-type:upper-roman;"\x3Eupper-roman\x3C/li\x3E\n\
\x3C/ol\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Col\x3E\n\
\x3Cli style="list-style-type:upper-roman;"\x3Eupper-roman\x3C/li\x3E\n\
\x3Cli style="list-style-type:upper-roman;"\x3Eupper-roman\x3C/li\x3E\n\
\x3Cli style="list-style-type:upper-roman;"\x3Eupper-roman\x3C/li\x3E\n\
\x3C/ol\x3E\n\
\n\
=== Mixed HTML list\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Col\x3E\n\
\x3Cli style="list-style-type:lower-alpha;"\x3Elower-alpha\x3C/li\x3E\n\
   \x3Col\x3E\n\
   \x3Cli style="list-style-type:upper-alpha;"\x3Eupper-alpha\x3C/li\x3E\n\
      \x3Col\x3E\n\
      \x3Cli style="list-style-type:circle;"\x3Ecircle\x3C/li\x3E\n\
         \x3Col\x3E\n\
         \x3Cli style="list-style-type:decimal;"\x3Edecimal\x3C/li\x3E\n\
            \x3Col\x3E\n\
            \x3Cli style="list-style-type:disc;"\x3Edisc\x3C/li\x3E\n\
               \x3Col\x3E\n\
               \x3Cli style="list-style-type:lower-roman;"\x3Elower-roman\x3C/li\x3E\n\
                  \x3Col\x3E\n\
                  \x3Cli style="list-style-type:none;"\x3Enone\x3C/li\x3E\n\
                     \x3Col\x3E\n\
                     \x3Cli style="list-style-type:square;"\x3Esquare\x3C/li\x3E\n\
                        \x3Col\x3E\n\
                        \x3Cli style="list-style-type:upper-roman;"\x3Eupper-roman\x3C/li\x3E\n\
                        \x3C/ol\x3E\n\
                     \x3C/ol\x3E\n\
                  \x3C/ol\x3E\n\
               \x3C/ol\x3E\n\
            \x3C/ol\x3E\n\
         \x3C/ol\x3E\n\
      \x3C/ol\x3E\n\
   \x3C/ol\x3E\n\
\x3C/ol\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
\x3Col\x3E\n\
\x3Cli style="list-style-type:lower-alpha;"\x3Elower-alpha\x3C/li\x3E\n\
   \x3Col\x3E\n\
   \x3Cli style="list-style-type:upper-alpha;"\x3Eupper-alpha\x3C/li\x3E\n\
      \x3Col\x3E\n\
      \x3Cli style="list-style-type:circle;"\x3Ecircle\x3C/li\x3E\n\
         \x3Col\x3E\n\
         \x3Cli style="list-style-type:decimal;"\x3Edecimal\x3C/li\x3E\n\
            \x3Col\x3E\n\
            \x3Cli style="list-style-type:disc;"\x3Edisc\x3C/li\x3E\n\
               \x3Col\x3E\n\
               \x3Cli style="list-style-type:lower-roman;"\x3Elower-roman\x3C/li\x3E\n\
                  \x3Col\x3E\n\
                  \x3Cli style="list-style-type:none;"\x3Enone\x3C/li\x3E\n\
                     \x3Col\x3E\n\
                     \x3Cli style="list-style-type:square;"\x3Esquare\x3C/li\x3E\n\
                        \x3Col\x3E\n\
                        \x3Cli style="list-style-type:upper-roman;"\x3Eupper-roman\x3C/li\x3E\n\
                        \x3C/ol\x3E\n\
                     \x3C/ol\x3E\n\
                  \x3C/ol\x3E\n\
               \x3C/ol\x3E\n\
            \x3C/ol\x3E\n\
         \x3C/ol\x3E\n\
      \x3C/ol\x3E\n\
   \x3C/ol\x3E\n\
\x3C/ol\x3E\n\
',
'= Tables syntax\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
{|\n\
| CELL1 || CELL2\n\
| CELL1 || CELL2\n\
|}\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
{|\n\
| CELL1 || CELL2\n\
| CELL1 || CELL2\n\
|}\n\
\n\
\x3Cdiv class="woas_helptext"\x3EOr use this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
{|\n\
| CELL1 || CELL2\n\
|-\n\
| CELL1 || CELL2\n\
|}\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
{|\n\
| CELL1 || CELL2\n\
|-\n\
| CELL1 || CELL2\n\
|}\n\
\n\
The line that starts with {{{|- }}} is a comment line. You can type some text after it which will only be visible when viewing the source:\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
{|\n\
| CELL1 || CELL2\n\
|- This is a comment.\n\
| CELL1 || CELL2\n\
|}\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
{|\n\
| CELL1 || CELL2\n\
|- This is a comment.\n\
| CELL1 || CELL2\n\
|}\n\
\n\
== Header rows\n\
Tables can have a specially formatted header row created by adding a pipe followed by a plus symbol and a space before the title text (example: {{{|+ Title}}}), and can contain internal and external [[WoaS::Help::Links|wiki links]].\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
{|\n\
|+ TITLE\n\
| *HEADER1* || *HEADER2* || *HEADER3*\n\
|-\n\
| CELL1 || CELL2 || CELL3\n\
|-\n\
| CELL1 || CELL2 || CELL3\n\
|-\n\
| CELL1 || CELL2 || CELL3\n\
|-\n\
| CELL1 || || CELL3\n\
|}\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
{|\n\
|+ TITLE\n\
| *HEADER1* || *HEADER2* || *HEADER3*\n\
|-\n\
| CELL1 || CELL2 || CELL3\n\
|-\n\
| CELL1 || CELL2 || CELL3\n\
|-\n\
| CELL1 || CELL2 || CELL3\n\
|-\n\
| CELL1 || || CELL3\n\
|}\n\
\n\
\x3Cdiv class="woas_helptext"\x3EOr use this code in a page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
{|\n\
|+ TITLE\n\
| *HEADER1* || *HEADER2* || *HEADER3*\n\
| CELL1 || CELL2 || CELL3\n\
| CELL1 || CELL2 || CELL3\n\
| CELL1 || CELL2 || CELL3\n\
| CELL1 || || CELL3\n\
|}\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
{|\n\
|+ TITLE\n\
| *HEADER1* || *HEADER2* || *HEADER3*\n\
| CELL1 || CELL2 || CELL3\n\
| CELL1 || CELL2 || CELL3\n\
| CELL1 || CELL2 || CELL3\n\
| CELL1 || || CELL3\n\
|}\n\
\n\
= Extended customization of layout\n\
\n\
Styling, formatting, and alignment can be used to control the look and behavior of tables. All example tables on this page use table comment lines ( {{{|-}}} ) to make it easier to see what is involved in creating the tables. These lines are not necessary when creating your tables.\n\
\n\
== Add some custom CSS rules to the wiki\n\
To create a custom table defined by [[WoaS::Help::CSS|CSS]], add some table rules to the wiki CSS using a class name of your choosing.\n\
* \x3Cdiv class="woas_help_text"\x3EUse these CSS rules in your wiki, replacing CLASS_NAME with the class name you\'d like to use, and CSS_RULES with the rules you\'d like to define for the table, the caption, the headers, the cells, and a [[#Styling table cells|special cell]]:\x3C/div\x3E\x3Cbr\x3E{{{\n\
table.CLASS_NAME {CSS_RULES}\n\
caption.CLASS_NAME {CSS_RULES}\n\
table.CLASS_NAME th {CSS_RULES}\n\
table.CLASS_NAME td {CSS_RULES}\n\
table.CLASS_NAME td.special {CSS_RULES}\n\
}}}\x3Cbr\x3ESee the [[#The CSS rules used by the example tables|custom CSS rules]] used by the examples on this page.\n\
\n\
== Assign a class to a table\n\
When custom CSS rules have been added to the wiki, you can replace the default {{{{|}}} table opening line with a custom one to assign the custom class to the table.\n\
\n\
\x3Cdiv class="woas_help_text"\x3EOpen a table with this line of code:\x3C/div\x3E\x3Cbr\x3E{{{\n\
| class="CLASS_NAME"\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_help_text"\x3ETo use a custom class for the table.\x3C/div\x3E\n\
\n\
\x3Ctable width="100%"\x3E\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample default table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{|\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
|} \n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{|\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
|} \n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\n\
\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample custom table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{| class="mycustomtable"\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
|} \n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{| class="mycustomtable"\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
|} \n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\x3C/table\x3E\n\
\n\
== Alignment\n\
Tables are aligned to the left by default, but alignment can be controlled by surrounding the cell contents with extra spaces or tabs. Forcing content to the left is not necessary, but it may help to use forced alignment for debugging complex tables.\n\
\n\
{|\n\
| *Alignment* || *Example result* || *Effect*\n\
| {space}text{space} || text || default\n\
| {space}text{space}{space} || text  || text is aligned to the left\n\
| {space}{space}text{space} ||  text || text is aligned to the right\n\
| {space}{space}text{space}{space} ||  text  || text is centered\n\
|}\n\
\n\
== Captions\n\
Placement of the caption determines whether it\'s above or below the table.\n\
\n\
\x3Cdiv class="woas_help_text"\x3EUse this code in a table, replacing CAPTION with the caption of the table:\x3C/div\x3E\x3Cbr\x3E{{{\n\
|+ CAPTION\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_help_text"\x3ETo add a caption to a table.\x3C/div\x3E\n\
\n\
\x3Ctable width="100%"\x3E\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample default table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{|\n\
|-\n\
|+ caption above\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{|\n\
|-\n\
|+ caption above\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\n\
\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample custom table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{| class="mycustomtable"\n\
|-\n\
|+ caption above\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{| class="mycustomtable"\n\
|-\n\
|+ caption above\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\n\
\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample default table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{|\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
|+ caption below\n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{|\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
|+ caption below\n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\n\
\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample custom table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{| class="mycustomtable"\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
|+ caption below\n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{| class="mycustomtable"\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
|+ caption below\n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\x3C/table\x3E\n\
\n\
== Empty cells\n\
Empty cells can be created by inserting just one space after a pipe in your table.\n\
\n\
\x3Ctable width="100%"\x3E\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample plain table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{|\n\
|-\n\
| || cell 2 || cell 3\n\
|-\n\
| cell 1 || || cell 3\n\
|-\n\
| cell 1 || cell 2 || \n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{|\n\
|-\n\
| || cell 2 || cell 3\n\
|-\n\
| cell 1 || || cell 3\n\
|-\n\
| cell 1 || cell 2 || \n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\n\
\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample fancy table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{| class="mycustomtable"\n\
|-\n\
| || cell 2 || cell 3\n\
|-\n\
| cell 1 || || cell 3\n\
|-\n\
| cell 1 || cell 2 || \n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{| class="mycustomtable"\n\
|-\n\
| || cell 2 || cell 3\n\
|-\n\
| cell 1 || || cell 3\n\
|-\n\
| cell 1 || cell 2 || \n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\x3C/table\x3E\n\
\n\
== Headers\n\
In default tables, table header cells ({{{\x3Cth\x3E}}}) are created by surrounding the cell content in asterisks. In custom tables, use a single {{{=}}} symbol before the cell content to change the table data cell ({{{\x3Ctd\x3E}}}) into a table header cell {{{\x3Cth\x3E}}}, which can be styled differently through CSS.\n\
\n\
\x3Ctable width="100%"\x3E\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample default table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{|\n\
|-\n\
| *cell 1* || *cell 2* || *cell 3*\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{|\n\
|-\n\
| *cell 1* || *cell 2* || *cell 3*\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\n\
\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample custom table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{| class="mycustomtable"\n\
|-\n\
| =cell 1 || =cell 2 || =cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{| class="mycustomtable"\n\
|-\n\
| =cell 1 || =cell 2 || =cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\x3C/table\x3E\n\
\n\
Placement of table header cells ({{{\x3Cth\x3E}}}) can be anywhere in a table.\n\
\n\
\x3Ctable width="100%"\x3E\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample default table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{|\n\
|-\n\
| *cell 1* || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || *cell 3*\n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{|\n\
|-\n\
| *cell 1* || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || *cell 3*\n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\n\
\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample custom table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{| class="mycustomtable"\n\
|-\n\
| =cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || =cell 3\n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{| class="mycustomtable"\n\
|-\n\
| =cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || =cell 3\n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\x3C/table\x3E\n\
\n\
To get the contents of a cell to start with an equal symbol, use an HTML comment ( {{{\x3C!-- --\x3E}}} ) before the equal symbol:\n\
\n\
\x3Ctable width="100%"\x3E\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample default table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{|\n\
|-\n\
| \x3C!-- --\x3E=cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || \x3C!-- --\x3E=cell 3\n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{|\n\
|-\n\
| \x3C!-- --\x3E=cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || \x3C!-- --\x3E=cell 3\n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\n\
\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample custom table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{| class="mycustomtable"\n\
|-\n\
| \x3C!-- --\x3E=cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || \x3C!-- --\x3E=cell 3\n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{| class="mycustomtable"\n\
|-\n\
| \x3C!-- --\x3E=cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || cell 2 || \x3C!-- --\x3E=cell 3\n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\x3C/table\x3E\n\
\n\
== Spans\n\
By removing all contents in a cell you can cause the content in the cell to the left or right of it to span more than one column.\n\
\n\
\x3Ctable width="100%"\x3E\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample default table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{|\n\
|-\n\
| *cell 1* || cell 2 || cell 3\n\
|-\n\
| *cell 1* || span last 2 columns ||\n\
|-\n\
||| span just last 2 columns ||\n\
|-\n\
| span all columns ||||\n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{|\n\
|-\n\
| *cell 1* || cell 2 || cell 3\n\
|-\n\
| *cell 1* || span last 2 columns ||\n\
|-\n\
||| span just last 2 columns ||\n\
|-\n\
| span all columns ||||\n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\n\
\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample custom table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{| class="mycustomtable"\n\
|-\n\
| =cell 1 || cell 2 || cell 3\n\
|-\n\
| =cell 1 || span last 2 columns ||\n\
|-\n\
||| span just last 2 columns ||\n\
|-\n\
| span all columns ||||\n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{| class="mycustomtable"\n\
|-\n\
| =cell 1 || cell 2 || cell 3\n\
|-\n\
| =cell 1 || span last 2 columns ||\n\
|-\n\
||| span just last 2 columns ||\n\
|-\n\
| span all columns ||||\n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\n\
\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample default table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{|\n\
|-\n\
| *cell 1* || *cell 2* || *cell 3*\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || span last 2 columns ||\n\
|-\n\
||| span just last 2 columns ||\n\
|-\n\
| span all columns ||||\n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{|\n\
|-\n\
| *cell 1* || *cell 2* || *cell 3*\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || span last 2 columns ||\n\
|-\n\
||| span just last 2 columns ||\n\
|-\n\
| span all columns ||||\n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\n\
\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample custom table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{| class="mycustomtable"\n\
|-\n\
| =cell 1 || =cell 2 || =cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || span last 2 columns ||\n\
|-\n\
||| span just last 2 columns ||\n\
|-\n\
| span all columns ||||\n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{| class="mycustomtable"\n\
|-\n\
| =cell 1 || =cell 2 || =cell 3\n\
|-\n\
| cell 1 || cell 2 || cell 3\n\
|-\n\
| cell 1 || span last 2 columns ||\n\
|-\n\
||| span just last 2 columns ||\n\
|-\n\
| span all columns ||||\n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\x3C/table\x3E\n\
\n\
== Styling table cells\n\
Definitions can be used within tables to style the cells. A definition affects only the cells *following* it. If you wish to apply the definition to the entire table, insert it directly beneath the table opening tag.\n\
\n\
=== Method 1 - define styles in the wiki CSS\n\
This method requires that you add a custom "special" [[WoaS::Help::CSS|CSS rule]] to the wiki so that any table cell in the "special" class will use that rule. See the *table td.special* rule in the [[#The CSS rules used by the example tables|custom CSS]] used by this page for an example.\n\
\n\
You can add a "special" class definition by using {{{|$ class="special"}}} in a table. The definition can be used by any row below the definition by adding {{{==}}} before the contents of a cell.\n\
\n\
\x3Ctable width="100%"\x3E\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample default table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{|\n\
|-\n\
|$ class="special"\n\
|-\n\
| *cell 1* || *cell 2* || *cell 3*\n\
|-\n\
| ==cell 1 || cell 2 || ==cell 3\n\
|-\n\
| cell 1 || ==cell 2 || cell 3\n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{|\n\
|-\n\
|$ class="special"\n\
|-\n\
| *cell 1* || *cell 2* || *cell 3*\n\
|-\n\
| ==cell 1 || cell 2 || ==cell 3\n\
|-\n\
| cell 1 || ==cell 2 || cell 3\n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\n\
\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample custom table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{| class="mycustomtable"\n\
|-\n\
|$ class="special"\n\
|-\n\
| =cell 1 || =cell 2 || =cell 3\n\
|-\n\
| ==cell 1 || cell 2 || ==cell 3\n\
|-\n\
| cell 1 || ==cell 2 || cell 3\n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{| class="mycustomtable"\n\
|-\n\
|$ class="special"\n\
|-\n\
| =cell 1 || =cell 2 || =cell 3\n\
|-\n\
| ==cell 1 || cell 2 || ==cell 3\n\
|-\n\
| cell 1 || ==cell 2 || cell 3\n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\x3C/table\x3E\n\
\n\
=== Method 2 - define styles on the fly\n\
You can add a style definition by using {{{|$ style="CSSRULE"}}} in a table. The definition can be used in any row below the definition by adding {{{==}}} before the contents of a cell.\n\
\n\
\x3Ctable width="100%"\x3E\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample default table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{|\n\
|-\n\
|$ style="background:springgreen"\n\
|-\n\
| *cell 1* || *cell 2* || *cell 3*\n\
|-\n\
| ==cell 1 || cell 2 || ==cell 3\n\
|-\n\
| cell 1 || ==cell 2 || cell 3\n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{|\n\
|-\n\
|$ style="background:springgreen"\n\
|-\n\
| *cell 1* || *cell 2* || *cell 3*\n\
|-\n\
| ==cell 1 || cell 2 || ==cell 3\n\
|-\n\
| cell 1 || ==cell 2 || cell 3\n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\n\
\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample custom table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{| class="mycustomtable"\n\
|-\n\
|$ style="background:springgreen"\n\
|-\n\
| =cell 1 || =cell 2 || =cell 3\n\
|-\n\
| ==cell 1 || cell 2 || ==cell 3\n\
|-\n\
| cell 1 || ==cell 2 || cell 3\n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{| class="mycustomtable"\n\
|-\n\
|$ style="background:springgreen"\n\
|-\n\
| =cell 1 || =cell 2 || =cell 3\n\
|-\n\
| ==cell 1 || cell 2 || ==cell 3\n\
|-\n\
| cell 1 || ==cell 2 || cell 3\n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\x3C/table\x3E\n\
\n\
Multiple style definitions can be added to a table. The first definition can be used by adding {{{==}}} before the contents of a cell. The second definition can be used by adding {{{===}}} before the contents of a cell. The third definition can be used by adding {{{====}}} before the contents of any cell. And so on.\n\
\n\
\x3Ctable width="100%"\x3E\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample default table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{|\n\
|-\n\
|$ style="background:springgreen"\n\
|-\n\
|$ style="background:#ff00ff"\n\
|-\n\
|$ style="background:cyan"\n\
|-\n\
| *cell 1* || *cell 2* || *cell 3*\n\
|-\n\
| ==cell 1 || ===cell 2 || ====cell 3\n\
|-\n\
| ====cell 1 || =====cell 2 || ===cell 3\n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{|\n\
|-\n\
|$ style="background:springgreen"\n\
|-\n\
|$ style="background:#ff00ff"\n\
|-\n\
|$ style="background:cyan"\n\
|-\n\
| *cell 1* || *cell 2* || *cell 3*\n\
|-\n\
| ==cell 1 || ===cell 2 || ====cell 3\n\
|-\n\
| ====cell 1 || =====cell 2 || ===cell 3\n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\n\
\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample custom table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{| class="mycustomtable"\n\
|-\n\
|$ style="background:springgreen"\n\
|-\n\
|$ style="background:#ff00ff"\n\
|-\n\
|$ style="background:cyan"\n\
|-\n\
| =cell 1 || =cell 2 || =cell 3\n\
|-\n\
| ==cell 1 || ===cell 2 || ====cell 3\n\
|-\n\
| ====cell 1 || =====cell 2 || ===cell 3\n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{| class="mycustomtable"\n\
|-\n\
|$ style="background:springgreen"\n\
|-\n\
|$ style="background:#ff00ff"\n\
|-\n\
|$ style="background:cyan"\n\
|-\n\
| =cell 1 || =cell 2 || =cell 3\n\
|-\n\
| ==cell 1 || ===cell 2 || ====cell 3\n\
|-\n\
| ====cell 1 || =====cell 2 || ===cell 3\n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\x3C/table\x3E\n\
\n\
=== Method 3 - combination of method 1 and method 2\n\
These examples use a combination of method 1 and method 2. The first definition can be used by adding {{{==}}} before the contents of a cell. The second definition can be used by adding {{{===}}} before the contents of a cell. The third definition can be used by adding {{{====}}} before the contents of any cell. The fourth definition can be used by adding {{{=====}}} before the contents of any cell. And so on.\n\
\n\
\x3Ctable width="100%"\x3E\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample default table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{|\n\
|-\n\
|$ class="special"\n\
|-\n\
|$ style="background:springgreen"\n\
|-\n\
|$ style="background:silver"\n\
|-\n\
|$ style="background:cyan"\n\
|-\n\
| *cell 1* || *cell 2* || *cell 3*\n\
|-\n\
| ==cell 1 || ===cell 2 || ====cell 3\n\
|-\n\
| ====cell 1 || =====cell 2 || ===cell 3\n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{|\n\
|-\n\
|$ class="special"\n\
|-\n\
|$ style="background:springgreen"\n\
|-\n\
|$ style="background:silver"\n\
|-\n\
|$ style="background:cyan"\n\
|-\n\
| *cell 1* || *cell 2* || *cell 3*\n\
|-\n\
| ==cell 1 || ===cell 2 || ====cell 3\n\
|-\n\
| ====cell 1 || =====cell 2 || ===cell 3\n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\n\
\x3Ctr\x3E\x3Ctd width="40%"\x3E\x3Cdiv class="woas_help_text"\x3EExample custom table:\x3C/div\x3E\x3C/td\x3E\x3Ctd width="60%"\x3E\x3Cdiv class="woas_help_text"\x3EUse this code to create the table:\x3C/div\x3E\x3C/td\x3E\x3C/tr\x3E\x3Ctr\x3E\x3Ctd valign="top"\x3E\n\
{| class="mycustomtable"\n\
|-\n\
|$ class="special"\n\
|-\n\
|$ style="background:springgreen"\n\
|-\n\
|$ style="background:silver"\n\
|-\n\
|$ style="background:cyan"\n\
|-\n\
| =cell 1 || =cell 2 || =cell 3\n\
|-\n\
| ==cell 1 || ===cell 2 || ====cell 3\n\
|-\n\
| ====cell 1 || =====cell 2 || ===cell 3\n\
|-\n\
|}\n\
\x3C/td\x3E\x3Ctd valign="top"\x3E\n\
{{{\n\
{| class="mycustomtable"\n\
|-\n\
|$ class="special"\n\
|-\n\
|$ style="background:springgreen"\n\
|-\n\
|$ style="background:silver"\n\
|-\n\
|$ style="background:cyan"\n\
|-\n\
| =cell 1 || =cell 2 || =cell 3\n\
|-\n\
| ==cell 1 || ===cell 2 || ====cell 3\n\
|-\n\
| ====cell 1 || =====cell 2 || ===cell 3\n\
|-\n\
|}\n\
}}}\n\
\x3C/td\x3E\x3C/tr\x3E\x3C/table\x3E\n\
\n\
== The CSS rules used by the example tables\n\
These are the custom CSS rules used by the example tables on this page:\x3Cbr\x3E\x3Cbr\x3E{{{\n\
/* CUSTOM CSS FOR custom tables */\n\
table.mycustomtable {\n\
	color: #404040;\n\
	background-color: #fafafa;\n\
	border-collapse: collapse;\n\
	border-spacing: 0px;\n\
	border: 1px solid #6699CC;\n\
	font-family: Verdana, sans-serif, Arial;\n\
	font-size: 11px;\n\
	font-weight: normal;\n\
	/*UNCOMMENT THE WIDTH LINE BELOW TO CONTROL THE WIDTH OF THE TABLE*/\n\
	/*width: 500px;*/\n\
}\n\
caption.mycustomtable {\n\
	color: #404040;\n\
	border: 1px solid #6699CC;\n\
	text-align: center;\n\
	width: 580px;\n\
}\n\
table.mycustomtable th { \n\
	color: #404040;\n\
	background-color: #BEC8D1;\n\
	border-bottom: 2px solid #6699CC;\n\
	border-left: 1px solid #6699CC;\n\
	font-weight: bold;\n\
	text-indent: 2px;\n\
}\n\
table.mycustomtable td {\n\
	color: #404040;\n\
	border-top: 0px;\n\
	border-right: 0px;\n\
	border-bottom: 1px solid #9CF;\n\
	border-left: 1px solid #9CF;\n\
	text-indent: 2px;\n\
}\n\
table.mycustomtable td.special {\n\
	background-color: #ff00ff;\n\
}\n\
\n\
/* CUSTOM CSS FOR DEFAULT TABLES */\n\
table td.special {\n\
	background-color: #ff00ff;\n\
}\n\
}}}\n\
\n\
\x3C!-- NOTE: BELOW ARE CUSTOM CSS RULES EMBEDDED ON THIS PAGE FOR USE BY THIS PAGE. --\x3E\n\
\x3Cstyle type="text/css"\x3E\n\
/* CUSTOM CSS FOR custom tables */\n\
table.mycustomtable {\n\
	color: #404040;\n\
	background-color: #fafafa;\n\
	border-collapse: collapse;\n\
	border-spacing: 0px;\n\
	border: 1px solid #6699CC;\n\
	font-family: Verdana, sans-serif, Arial;\n\
	font-size: 11px;\n\
	font-weight: normal;\n\
	/*UNCOMMENT THE WIDTH LINE BELOW TO CONTROL THE WIDTH OF THE TABLE*/\n\
	/*width: 500px;*/\n\
}\n\
caption.mycustomtable {\n\
	color: #404040;\n\
	border: 1px solid #6699CC;\n\
	text-align: center;\n\
	width: 580px;\n\
}\n\
table.mycustomtable th { \n\
	color: #404040;\n\
	background-color: #BEC8D1;\n\
	border-bottom: 2px solid #6699CC;\n\
	border-left: 1px solid #6699CC;\n\
	font-weight: bold;\n\
	text-indent: 2px;\n\
}\n\
table.mycustomtable td {\n\
	color: #404040;\n\
	border-top: 0px;\n\
	border-right: 0px;\n\
	border-bottom: 1px solid #9CF;\n\
	border-left: 1px solid #9CF;\n\
	text-indent: 2px;\n\
}\n\
table.mycustomtable td.special {\n\
	background-color: #ff00ff;\n\
}\n\
\n\
/* CUSTOM CSS FOR DEFAULT TABLES */\n\
table td.special {\n\
	background-color: #ff00ff;\n\
}\n\
\x3C/style\x3E\n\
',
'= Links\n\
This wiki accepts wiki and HTML links.\n\
== Wiki links\n\
Below are methods for creating links using wiki syntax.\n\
\n\
=== Anchor link\n\
You can use a special anchor link to link to a header on the current page. After clicking an anchor link, use the browser\'s back button to return to where you were on the page.\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing HEADER NAME with the name of the header you\'d like to link to:\x3C/div\x3E\x3Cbr\x3E{{{\n\
[[#HEADER NAME]]\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create an anchor link.\x3C/div\x3E\n\
=== Email link\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing USERNAME with the name of the person, SERVER with the name of their server, and LABEL with the text you\'d like displayed as a link:\x3C/div\x3E\x3Cbr\x3E{{{\n\
[[mailto://USERNAME@SERVER|LABEL]]\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
[[mailto://USERNAME@SERVER|LABEL]]\n\
\n\
=== Email link with subject\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing USERNAME with the name of the person, SERVER with the name of their server, SUBJECT with the subject of the email, and LABEL with the text you\'d like displayed as a link:\x3C/div\x3E\x3Cbr\x3E{{{\n\
[[mailto://USERNAME@SERVER?subject=SUBJECT|LABEL]]\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\n\
[[mailto://USERNAME@SERVER?subject=SUBJECT|LABEL]]\n\
\n\
=== External link (labeled)\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing URL with the address of the web page, and LABEL with the text for the link:\x3C/div\x3E\x3Cbr\x3E{{{\n\
[[URL|LABEL]]\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create a labeled external link like this one:\x3C/div\x3E\n\
[[http://www.gnu.org/|Click here for GNU]]\n\
\n\
=== External link (plain)\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing URL with the address of the web page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
[[URL]]\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create a plain external link like this one:\x3C/div\x3E\n\
[[http://www.gnu.org/]]\n\
\n\
=== Image as link\n\
==== Base64 image as link\n\
See the [[WoaS::Help::Images]] page.\n\
==== Image as link to wiki page\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing IMAGENAME with the name of an embedded image page, and PAGENAME with the name of a page in this wiki:\x3C/div\x3E\n\
\x3Cdiv class="woas_helpcode"\x3E[\x3C!-- --\x3E[I\x3C!-- --\x3Enclude:\x3C!-- --\x3E:Image:\x3C!-- --\x3E:IMAGENAME|style="cursor:pointer" oncl\x3C!-- --\x3Eick="go_\x3C!-- --\x3Eto(\'PA\x3C!-- --\x3EGENAME\')"]]\x3C/div\x3E\n\
\x3Cdiv class="woas_helptext"\x3ETo create an image that links to a page in this wiki.\x3C/div\x3E\n\
\n\
==== Image as link to web page\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing Image::IMAGENAME with the name of an embedded image page, and URL with the address of a web page:\x3C/div\x3E\n\
\x3Cdiv class="woas_helpcode"\x3E[\x3C!-- --\x3E[In\x3C!-- --\x3Eclude:\x3C!-- --\x3E:Image:\x3C!-- --\x3E:IMAGENAME|style="cursor:pointer" border="0" onc\x3C!-- --\x3Elick="win\x3C!-- --\x3Edow.o\x3C!-- --\x3Epen(\'URL\')"]\x3C!-- --\x3E]\x3C/div\x3E\n\
\x3Cdiv class="woas_helptext"\x3ETo create an image that links to a web page.\x3C/div\x3E\n\
\n\
=== Include link\n\
You can include the contents of another page of this wiki in the current page by using an include link.\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing PAGENAME with the name of the page you\'d like to include:\x3C/div\x3E\n\
\x3Cdiv class="woas_helpcode"\x3E[\x3C!-- --\x3E[Include::PAGENAME]\x3C!-- --\x3E]\x3C/div\x3E\n\
\x3Cdiv class="woas_helptext"\x3ETo include the contents of another page in the current page.\x3C/div\x3E\n\
\n\
=== Internal action link (labeled)\n\
These are internal wiki actions in the form of links:\x3Cbr\x3E\x3Cbr\x3E\n\
{|\n\
| *Use this code in a page:* || *To create this:*\n\
| {{{[[Special::All Pages|All pages]]}}} || All pages listing\n\
| {{{[[Special::Backlinks|Backlinks]]}}} || Listing of pages linking to page\n\
| {{{[[Special::Dead Pages|Dead links]]}}} || Pages without any link to them\n\
| {{{[[Special::Delete Page|Delete page]]}}} || Delete page prompt\n\
| {{{[[Special::Duplicate Page|Duplicate page]]}}} || Duplicate page\n\
| {{{[[WoaS::CSS::Custom|Custom CSS]]}}} || Custom CSS\n\
| {{{[[Special::Go to|Go to...]]}}} || Go to page prompt\n\
| {{{[[Locked::|Locked pages]]}}} || Listing of encrypted pages\n\
| {{{[[Special::Main Page|Main page]]}}} || Main Page (whatever title it has)\n\
| {{{[[Special::New Page|New page]]}}} || New page prompt\n\
| {{{[[Special::Orphaned Pages|Orphaned pages]]}}} || Orphaned pages listing\n\
| {{{[[Special::Recentchanges|Recentchanges]]}}} || Recently changed pages listing\n\
| {{{[[Special::Search|Search]]}}} || Search into pages interface\n\
| {{{[[Tagged::Syntax|Syntax pages]]}}} || Pages tagged with \'Syntax\'\n\
| {{{[[Tagged::|Tagged pages]]}}} || Pages which contain tags\n\
| {{{[[Unlocked::|Unlocked pages]]}}} || Listing of pages without encryption\n\
| {{{[[Untagged::|Untagged pages]]}}} || Listing of pages without any tag\n\
|}\n\
\n\
=== Internal link (labeled)\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing PAGENAME with the page you want to link to and LABEL with the link text:\x3C/div\x3E\x3Cbr\x3E{{{\n\
[[PAGENAME|LABEL]]\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create a labeled internal link.\x3C/div\x3E\n\
\n\
=== Internal link (plain)\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing PAGENAME with the page you want to link to:\x3C/div\x3E\x3Cbr\x3E{{{\n\
[[PAGENAME]]\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create a plain internal link.\x3C/div\x3E\n\
\n\
== HTML links\n\
Below are methods for creating links using HTML syntax.\n\
\n\
=== Alert box link (button)\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing MESSAGE with the content for the alert, and BUTTONTEXT with the text for your button:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Cscript type="text/javascript"\x3E\n\
function alertme () {alert("MESSAGE");}\n\
\x3C/script\x3E\n\
\x3Cinput type=button value="BUTTONTEXT" onClick="alertme()"\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create a button that opens an alert.\x3C/div\x3E\n\
\n\
=== Alert box link (labeled)\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing MESSAGE with the content for the alert, and LABEL with the text for your link:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Ca href=\'javascript:alert("MESSAGE");\'\x3ELABEL\x3C/a\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create a labeled text link that opens an alert.\x3C/div\x3E\n\
\n\
=== Anchor links to anywhere on a page\n\
With a combination of HTML and wiki syntax, you can create anchor links to anywhere on a page, rather than just to headers.\n\
\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing NAME with the name of the anchor:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Ca name="NAME"\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3EUse this code somewhere else on the same page, replacing NAME with the anchor name:\x3C/div\x3E\x3Cbr\x3E{{{\n\
[[#NAME]]\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create an anchor link to anywhere on a page.\x3C/div\x3E\n\
\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3EOr use this code somewhere else on the same page, replacing NAME with the anchor name and LABEL with the text for the link:\x3C/div\x3E\x3Cbr\x3E{{{\n\
[[#NAME|LABEL]]\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create a labeled anchor link to anywhere on a page.\x3C/div\x3E\n\
\n\
=== Edit page link\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing LABEL with the text for your link:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Ca class="woas_link" onclick="javascript:edit()" title="Edit this page"\x3ELABEL\x3C/a\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create a link that opens the current page in the editor.\x3C/div\x3E\n\
\n\
=== External link (button)\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing BUTTONTEXT with the text for your button, and URL with the address of the web page:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Cinput type="button" value="BUTTONTEXT" onclick="window.open(\'URL\');"\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create a button that opens an external link in another tab or window.\x3C/div\x3E\n\
\n\
=== Internal link (button)\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing BUTTONTEXT with the text you want on the button and PAGENAME with the page you want to link to:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Cinput value="BUTTONTEXT" onclick="woas.ui.go_to(\'PAGENAME\')" type="submit" /\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create a button that opens an internal link in another tab or window.\x3C/div\x3E\n\
',
'= Images\n\
Wiki on a Stick offers various ways of using images in your pages. You can link to local image files on your drive, remote image files, or embed image files into the wiki.\n\
\n\
== Add an external image from the internet\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing URL with the full link to the image:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Cimg src="URL" /\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo add an external image from the internet.\x3C/div\x3E\n\
\n\
* *Example:*\x3Cbr\x3E\x3Cbr\x3E\n\
** \x3Cdiv class="woas_helptext"\x3EUse this code:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Cimg src="http://www.gnu.org/graphics/heckert_gnu.small.png" /\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\x3Cbr\x3E\x3Cimg src="%2BxS6AAAACXBIWXMAAAsSAAALEgHS3X78AAAAB3RJTUUH1AkZAiQF53xPugAAGFFJREFUeNrNXH9MVHe2%2F1QmS1OSaTrJmOUdZnYWybDsBJgSUXgID62BpayUEvz1RMKqhfW39Wmrr2qtGik1UnWFwKoLq0RXKWgJ9EHUrU83UOFJkUgDD3iwYKA7E9hlwmxmdoac98e9M8zcucMPq%2B1%2B%2F5mZ7733ez%2F3fM%2F3nM8553vnJcY%2FWVPMfNgyOm6xAAHBUKnUPzSi8QdfP%2B6xeHQE6mLiU4Oe%2FVbO%2FuG%2FjluhfFWp0s3wdC%2FJz9poXWNbgCFaF6IKETq%2BdT4d6Wl%2FGpixW%2FdMcIZr73bZVa8tBEz%2FMNmhjF2yMnweiNrK7ryamh7rK4%2Fh6ivjv94bOG88fYVNuoz4aKVLFwZ6vmnt1GVsDJY7mX1aczal1TuE7476hzZm7j6TueFM8yQz28oiEm7z%2FJrtpDb3kU%2Fv2PW12k0dvmf7IBrKpxT3LRsTiEJX7VlKQjNm7mvksX20aUiAa5sToPsJK5qZebLjwqal%2B%2B472NZ83iQc6d2jFYfyaJJZc5acC9q%2FEcDjyoWBgXfaXP0Bhk4AStUgCg4q2g%2F1rE8PGf%2FqyjXNjHNlDQIwfryuYK%2Bi6UrfU6FTtajTDuXuzcKSenyw%2F%2FiamfRodFtb%2Bgk1AGS0e66y8BMxn5%2Bwbtmi7KqtW1SqQu2VNgSE9fTMvPLOjq5UPLgWfTwMFUcVqZ2DQOo3w%2BKxRTFme%2FJ2wHmqZPUphV89ehipvy58uyrOk757cmhogpmZJyfFk86PMbNtiHdkzjJd9dpQ7YY%2FMvOxVZcn2HFhRT1PHFmXFJeUJgyuHRDOypz0p0f1%2BoRuZp7ovn8jQkTk0qih1ubmIYfnhRMfaJtn02hjvfAMvZIDjrXC6PmCsuozx%2BT1qGGb7jM1cCdP%2BJlqABa9BYw%2BaOnsmwKAgDBDVFSYCrAP999pmCpOn23RN717Imv612DPoBUIMRgAc4oZAJCs%2BXFyNFo3%2FrwqSEaP2leHfKYGnMmDAIDwuwBgqalrgy42epEmwDzc0%2FX1uOvsRb%2FYMgev0rT%2FtfSfAhifGP22a1xl%2BDHsXf2qNzcaTHZ8e%2FYeACi%2FUqIlb1m5wgfReKrzi2AAJYXC78KNgKXkoj02PdVjRZm7vwXwmvqnyrmZRmtTe78TQEiQ%2BmdRgj0cbbzZnnw0DLiXAwAoOAw0bNty2Eez87UdzMzNemGKI23MNUbtnl5%2BAa17q77IwSyYudAhZq6hRqlm11MZM3dkC3gyL4%2BxbQ%2FlDvALao8S0kx8O4WIiOKuM%2FMm%2FYg3ItviVQ5m3iSsyhFmnsx2WYIX0iY3GHuZO3YSEdEx5rHIXG9Ep7W9zMwrBNDM7Mg0dvCLbI53jEPMQ0REtI6Z613ztkBwxhfzwgBAWGZqAAcHq6NnU9vx4eHh0WcmZqWGAjteFSgFgPTET5wejO2ifQcAjNoBAEqg9kZ12Ezjjd5p6RqcAgDoYt9aJuF9zrtffj1sgea1sPhUlX9IbxYeFZbsIAAcSm14y7367XFZhwHg7CkAUJYsty7LOjwDnq7iO4YlP9colYD9ac%2BXLaqNWzysgbP2VEBWjC4QFnNf%2B734LfH%2Bhml%2Fuy56cxMA1MUA2Gypdq%2F%2BW1oTM%2FMxIiJaMcBcZJz0rwFjW0OPeBmFkdMRxlvuX0%2FSjNen%2FY2tJmGDXwuyJ5sdB4iIjB3MfJ%2BG3Jq9KZeZuUZY%2BWPMptAZltkfIzb4cBpbkXaP%2BAwVoflj3ip8OeKCn6FGQjuY84mIIpiZF1cwMysAWO%2BdAoAoQZY98TgfnOV3xioO798tfLM%2F7jEDqpCohQh87638jEs6wLm%2F9j8LAGC0fdAeHGUAoNiYWNB%2FXDbCCM6qisYwAGgAIFVwqcx8Wys8n5GIiM7z2AwiuqCtF%2BnuplCRH1DKBRvzZLa%2Bnh3vUFzFCNtqMoUji4%2BZmJknM99xyI7WEemwaYmI3mdmvq13%2Bf7jbXUAgG11AJBcVXLxK3%2Fk%2FuLx0nQAzsrKQc9u3bkYOLd9kTHYCSBgZVSl2U328nYrAWtOyG9kx1t2KiALAIrXALD8%2FG44sABAT4wYIgAADKjL8AeoQgB0L%2FmoFyAMvl0LxW%2FfrOsE4nOCmk4tWe06Yi9f9jkQVNX5oTyizp8pAeApAChDuiEiWiR4%2B3sAoNk12rXcD6CGo0fTAeu7OYPSI1O7LgKlGev3pra0Ve8Navhql5vwjG8vsCLoD3UlciMa2pW7AeDsAwAI6xH1iJo9iOx%2FcSP5WfoPQ08yc28cybYLQmxyPyJpYmQr6Y8Zpw8lmZgf6e%2FLxSlp7EggIoocYuYDOwUvMopgAM4yAEDiLzAYLE%2Fo%2B7akHgRa04flBXj0%2BKEAAImXBsuCS4ttF%2FOmjWb%2Fm32IKdwuc2HwX6EoAIAJCwD1qDBrTgQAUJQGAsCwE1Z5cmjeuOgc0LTe6s8ulI8qACB%2BYzWwpgqleR5OZ6MZWalb7D7XBA4DdQDwngGASkQEwd8ZjgLAYDUgKyJr9o8uKdCSb%2FfvXESumToKIPE966BHDD2cY0VhgKx2t7QAiCkAgCCLC5Eg3zU6APhE%2Fpb2HEuVCj15U7PnWRRBAJAX1BLr6QoPQVF%2Bs0nmqhIACBDW%2BbgLkRkAhjMGAWDchKcy1737TaUG5nXWmQjBhLi4VAAQFG72siHVN6Ap3C8lL0%2BDEA8AbW%2F3uboWAIANgDWrCwDwa9nI%2BXjduWhYc8wzUp5vhY8oqxkArIvGvY4e7kHWG7ucktUSAiGmsVg9EAnCDqrSAIB6O4KHfSbuWvnhVGB%2F10x4VMHiY2rKD%2FUBj3uy7nkr4jY7PhqVWKX%2BMASuAbDoZrQHomDh4cIblgFQmhCOdqllPLCxACis8w%2FHcKqts2HUJPyIL%2BmEZdf2WonO9XwIZXlpq1dfd6zzbBmg%2Fmw6T7YAQKCgAKrdAPpTS6JUn3sP1bor8ThwzcfoKjWipkRdalofjIWGBpeKZ3Wt%2Bvf1H1dXnYrxPL%2FqBgzHd3vOpaVt5d1TU4D5PADAFCCuj4WCejTtAgB7w%2FbVlf%2Bh9rKMYeUKNB3wHDxgSXKMQQn0tY0G6cTQEOs%2BTRSp8JXi4uXQAQhshyGk06XP%2B9XL1%2FQXXJtmJjcMOuHel%2FARAMu%2FiF4k%2B6SQoxBMfi5PROR7GPpeY5KJ%2BWHotFMwbqpx%2BxmvrNYB%2FWUHM%2FMto4s2DtFOZh6pyRcGj%2Bhl3jrNTCYiG8VohOgWM%2B9MEznkzk3M%2FLdc8Z4HmK%2FTBQ9AxgHmh0Koq82%2FNeDNdE578ckLEQlnupn3nHf36K8KnwNbiYgowcSOd3Jdz7N1FbONiCjz6ggz86p8EVHZYiGou72BiOgMMx8g15hXIxIGmG%2FriYi0B3zo7FXy7po4n0lJ109nuyWXvcf17Vao6HQdW5OamZkdB4xDzJN6F2FjjigSEd2nvwiQVhARFU0yO%2FZR%2FgAz966jXBNzhZaIaJM05h5ZG0nkItUdpyf4PjPz2OWE3D1J3S4cIudkl5yTBpgvaNddbr6QkNTLlzO103mqAWoUEU1oa5iZeYeY%2Blp1nbnGSCnZCWSsYR7LJyIy1nvDKVuXnUBERrd0QkPjSMBs23Tm9CZmnixad5Ivh7ovvC3oUj1z774Vcbm%2FszFHiloUaWLmy9oJV0brzbBzAK4cdFuXJsBa12kLNqwMRO3RcQDJ57xDwcKS4KgmAKs%2FdfXcK38AMSi49iC8%2Fxwsq%2FqBm7FN22pd1u%2BTc4K92p7s4hOvCzY1JyxWBax23nTFa2f0NmbuuHUyQZTS9AJqFnKGJyUT1kgJk%2FeJiFo9Oov2pDEzPyky7otoZT5JRGttzEdS3Asz0xUrdDBz75MxQWoUMSGsy%2BvueE38ziYxeUQdbOplZu4VszcfSDXaSI3cLOYQPEPCDma2%2FW7Ph93MtgiitQ5mHiGTO1nuym%2Fqn3Cvnkg0OFTEzHwkwjadG9mQJgzosjiRWqLzzA9FZpotjW0ekZG5mcgoptp7mzsczMwD%2BzwIKxHVDzEzR0wLst5t0zqSPBhxqInZFHqaXREkkJfXEg88rnazdQCFwSEbBYesPKeQRpGIBwYRXq4Bxq81DauUPbG%2FB6BzDrodVCcQcOPO3w%2Fq8Oq0w09PFz2N2SOtmpcOAGcDt3jmIVNfuQk0dcF5zsNTvCwyhFPrJUW3SFVpPMzvxhco4Lz0ID05GLAmn0gF8PjEJRe9PngFsTeB9hjEF08nI4aX%2BXI%2B9X8rgcF%2FO7xlmh8Bh9o%2BB1L37m3zjHhEQDESQPjy1ep44JWq7QqM1yZXrQ8GEJR6BQCix4%2B7zrIBGQBiYJ%2FwSJxoVkrxpGdoKgB8qMnzYqKJ6SeWK4HKFgSbpA9xUPL7QVWdDiIbV7mLGppaIensJkVB2PUrIQ7WGDyuTpUyW4Fi1951OWBRRjhhPQDg9ZanbVLe%2F4Z3%2Fsf%2Bub1apujntFnGAWDjqItnqpAIy73q6os3yj1PTPa%2Bbr%2B6FQDMR1cnSqqi6hO7EtcjGuiyBOm8uOJeya3fmubSACztw%2F1f9kMzMoWm9QDiU1tFnV2Ee2X3pgAEPvB8goWG6dFDnuJX6QcBOHcGfuTFswEgK%2BdoDwC0aOpygAD3VfGSdKQgQpe%2BFb%2Bec%2FBiPzD8clT8RQsAHG1xGX6U3J0CAPvBG54DrHbLECd0OmVYqRMoaSlX%2BiDC4UV5ZgABDeExwHvu7gJZFuviptVuSl5YXdcHAJoYcdrCFgX8qQAA3gio9rx0jRqAUoOjyoD4gwZArcDnpz6KkatmjSxeJRAXh36fLZQWbyCtlhLkUwCu5HOctugvJhetcrEA16f2SBwRUe%2FJOAmDIaLr1NyYxtwscMUjfqpZT%2FSZQiktd4zXhnbk0wdE5%2BXz46vELxsSJnlCS0S0j1nKVs5rQ4mI%2FsLeaUDOJqJHW5td0Cu0Bxz%2B6rQP9UkDzMxjzOevc3ZKPWnHZBE1u2Q0ZNzk4GNEpH%2FEvT4p%2BVwioiOOh42SUrCeqGLsichidtDpGSrHHcZIkc1MMm%2FoPUm58pN2%2BkP36Gmrmrlm37FudhxzdEtOm4hb1dzdmhD5RNJfQ7RTZAPXjYtvz1jLHkmjrS7hP%2BFsqpFHlFkxnYr9XULmmVvNzVfXPuQyH1lqUyIpdKfP9TsodIKZe88sDT0yMXMtG85zZxUZecKKd4ajUzZPMhpb5xmIDbYPDr8cnq525lVJzywsMSS%2FuaZTmkW0b2vK0nV1jqrXyNQNffAP7NFSSlGzjbmDNsiL6DxNyHUXnfStx6QcY15R79ufRpTy4X25DC7kEt9FSUTalK25VCFf9lkcKbf%2BLlyWucEjbTefXOe7VaGe%2FNXuIN89cHnnCi3RkOzB65Qy96rVgTRuJqMPWBM9mh8iZmbHUqN80TyOsueOaCziqk2fHbpCahq0ZX4uWDBDykzzsmx%2F2fB86miqguP2jNgmZUald3%2F0FX%2FZsRkeLztOtuwbmrQvYR7FxonQottJ7CjTrmr1yhtrEzasG5vfrHGaHKLJFdT8RGubB6QP9A9pgvlJGqVd8ChsNa6NoxvzQzSgTZPp3UofMKfcnweiAe0mGmJmR022loxF04bjDD2ROd3%2FPjbngalE397CuvDDQE5dop%2FNYXXtFqjDohI9bKJuzTWYNYAiK8veXVdetT4%2B%2BBUAPbV1bxvmpUf7KNe3GnFBCNEcv5QtVAzla8mYnZ0ZSUZP92OK9Mj%2BjLzvKk8sPeOY1%2BpvpiTfC4pIzFV1nJStlunPCPsInuyg%2FAlP95Y0ycwD9YL62YaGhoaGxuZrj4roso9Sb6UVLtWsMflesiL04bTeRsR5%2BI5G%2FdI9G4xESU9mVzu%2FiPaISSUPESTQhunJ8jW5j%2Bjk7RUUeUQQ7cg6yp42%2BU%2ByKWLD1asrZt2zNAOiVUkSs39AS%2BSYaagKOqKNKLp%2F%2FoJ7z2CoVMyTmRueGVENbfX82ft%2BKOmJZhzqDBFdFciey51G7pM8w%2FXQWS2Z%2FOq3FpfDHa3au1oaOhG0%2FfWNM%2FuLMAA6wNz8j4AYIUJLX5KzrdTrDgZ796ybP2RXcRJliia%2F%2BViKlogijph4bJZZm4yI1E9wt56IaIe4kib3ZXpR3SF%2FrHRmGdlz%2Bt8UHq1vVycQaFiyLDEQUKnGB2faTBK0vaE6CHesgNJ%2Bs%2FMzNQAEneq6FpzjSURn3foih%2BhG%2F%2FpCBQB05ZgRMPWeK4gMb2mXIrKWjGqiXOmOgm4AMQBif3O6cmeVMLRBYpftsyGSYyNNykJFz5UGc2WWeXtnNFTTitLic%2Bq5mAx3%2FkXx6d%2BB%2BO0BiFF%2BVNpyRe52TxH8LDJqD%2F9ToZAuKDgIj5Ka2lVB88gxpXqqu0IN4OB2uxpI33vpV7LRefizyGiqPac7Jt0ApL83XTMFAPxYemrGJcAyLJaDRAqmVAPA9qB2mT1UleqoZ5HR0XNRB3XAOFQArJ6IfEQeCCCw88ZUeRDQN%2BiZP1Ns7orxMSqbzccVeJbV79mI3Ib%2FtCQe9iBlW5kn3pEYA5%2BUwWQmveOY1WYvmJ0pB06njhr8UOzDX9%2FBjbckxkCaiRvPa8sonV1Ec5CR21%2F26knrx8DdSrD5sKm%2FSSK0SDo2F8q5YB5hRVhP3tQd%2BUNvBZVZpAH5q167bzYX2M8dnstd5oMISIbFz5FtxTPtZ3%2F87r81RdVm4TkhMns6U38bjtM1fo3x4NnUjM6VWGSY42PPNq168iBZk5Tv77zr5IeMTTR3jDDz%2B1Q2t9BlVkRx5JnZCE3wt3wdCQkzrmxHLuVPPhfNVnvOGkIG179bIW9qTwyem9EU%2F%2F7ivW3PRY9C4LlFLBot1Ycvymt9%2BtkZd3HgF6vvmp8HojAMeJrChvK34UcWhaqC8Zk3tMP5PDS7niTpKxuRH658X%2FKehUTDT2vnlHZ6abY36kZj0ebtYGNHdRrd5jDZ%2FaRRpV6%2Bw9TS1j%2FyD7yiekXV%2F3hKPfN%2BZtl3auRa3NMSb49V8bEVSL0kd%2B6VQ0hPjl4kMOKulpZ%2BL5N1Yk7v5M2O6EBVzse%2BKdjkKvkNzoUtADRqmEemAJ1BFwiYx0dHR1GQp5mbgZwd0YP1IV9JncIWU%2FUSfxb6TkvfUztUi6Jfj1%2Fo7i0u%2FkaJ52Sz2RFJ0lz%2BYj%2FlEv%2Btkeb81sDsfk2xGo1SbUc65tdC8Pe5njoHT7sR1ZIeHbrwwtocEOneGLwnKd3iUNv8btMH9XNEhB2QuLItKvPbb5fU9s0d0V1l2FxPnQPvRWzi3S4vcqOpvtjX2QaIoa%2FfZjGZLRYgJHj4Tuqcwb80l7ege1L%2B9Zq0rysVwJu%2F9ePB%2Bga%2FGex7Op1DV36he54yQnjepTvSvQxKAPiiMk%2FGILV1edCF4Kjw4JdfiVc9XxnBujLgrrRGdm10vNai%2FhoQXwoV29k%2FeEVQlSvnvdjmZrbuaz%2BU6b0tZN0ca23eoaOWKKVxcuBqxNzioXmyWnc8%2B0eZUJaWMrNtK4149%2FeeueVgZo7Q214cIs6NGJF2lRGdZMfpCAqVv8REK%2FgFIppMSpuU5uApcoLfF194k8330jO8JDjnCDLoM4tkc%2FUVIEOJmwCGK%2FpqD8kw1uLA48%2FgRuZRAzJ%2BIKkK0C9drwYJ71d6MgZR%2B7pfnIwAXXVTsZcvUePrQ04xZ5Yq4WOjrQCQjgcvwtNOhyXXPvd0cKrKIFRmBcqkHQDgawB4xW%2Be4DllIsI%2Bq%2FbMd0bfCEb7XWGz0og0Bdot7PcLebGIoK5ubfCEdDcdAHbrgHuSXFejAmY8PqRc%2FiI1W6x%2B1EvzVJRiMhKleW2T6NBeHtl0W0%2F1L9AeTVPmL73N4Fqixhryrp09MmoHMiN89iu%2FIEQ85L3QHb%2BktY4EItKeFMU0cUxLS%2BOI9kw8AyB%2B6bv%2FS8zmpqCe1tVTAALLVwKWi8IWu4DS9GcabsF3xeMsb0IUlpQGALBbgTvLioUVH%2FZsgL4zohvxxxF4CEivBICFaN3syo%2F0dP0giB7vHVWtvhsNCBGUBcXTe2D3O38IRP%2BL452f6gBcqxMKMX%2BePta5zfkDIHodQvHDIjj5WqtnLeeLjHY4HwNm5%2FeIKGyvsOX4mgVRAMzv%2FtrzaGdGiO4U%2BioU36dm7xp%2FDAAPsP09APjiE0l5Sbm%2FeP3GeY2o%2BI6IFL9pFWKl%2FaMBUwB6pEFUlvMPwd%2BvPcISAMiCRbNb7uhTZ2n8%2FMYLOPpcEhqhE08SYv%2FPLSCl0%2BUK1JeXf79rzd0%2BUvUpTi2D8CcTUNWJeYLEuiXzHek5yQiICfzRjzL%2F3I31if%2FD%2BNtPihe0TwGa5d0tpp%2FOT1dfer7%2Fx1b5ifXjZdX3Hk%2B9sUP35TfDdvXPlhnmOcRzRoTx2i7N%2BmDnoPnpT5Y82wgv%2FdP9Z92CfzZA%2BH8h6HFxmnJRXwAAAABJRU5ErkJggg%3D%3D" /\x3E\n\
\n\
== Add a local image from your hard drive\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing PATH with the full path to the local file you\'d like to display:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Cimg src="file://PATH" /\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo add a local image from your hard drive.\x3C/div\x3E\n\
\n\
* *Linux example using a default Kubuntu image:*\x3Cbr\x3E\x3Cbr\x3E{{{\n\
\x3Cimg src="file:///usr/share/icons/default.kde/16x16/actions/stop.png" /\x3E\n\
}}}\x3Cbr\x3E\n\
* *Windows example using a default Windows 7 image:*\x3Cbr\x3E\x3Cbr\x3E{{{\n\
\x3Cimg src="file://localhost/C:/Documents and Settings/All Users/Documents/My Pictures/Sample Pictures/Blue hills.jpg" /\x3E\n\
}}}\n\
\n\
== Embed an image in the wiki\n\
This wiki provides an interface for embedding images. Each image will be given its own page, which you can use in an include link to insert the image anywhere in this wiki.\n\
\n\
[[Include::WoaS::Template::Info|Embedded images are encoded with Base64 and are 33% bigger than the original files. Since this wiki is a single file, excessive use of images will slow down performance.\x3Cbr\x3E\x3Cbr\x3EIt is recommended to keep the extension in the image name because some browsers infer the mime type of the image from the extension.]]\n\
\x3Cspan class="woas_helptext"\x3EReplace NAME in these instructions with the name of your image:\x3C/span\x3E\n\
=== From the menu\n\
# Click the *New Page* link in the menu.\x3Cbr\x3E\x3Cbr\x3E\n\
# Type {{{Image::NAME}}} into the box that comes up. This will bring up the image embedding interface.\x3Cbr\x3E\x3Cbr\x3E\n\
# Browse to the image on your computer.\x3Cbr\x3E\x3Cbr\x3E\n\
# Click the *Embed* button.\n\
\n\
=== From any page\n\
# Create an include link for a new image by typing {{{[[Include::Image::NAME]]}}} into a page, or click the editor\'s *Image* button and type in a name for the image.\x3Cbr\x3E\x3Cbr\x3E\n\
# Click the *Save* icon in the navigation bar to save the page.\x3Cbr\x3E\x3Cbr\x3E\n\
# Part of the include link you just created will be red, indicating that the image doesn\'t exist yet.\x3Cbr\x3E\x3Cbr\x3E\n\
# Click on the red part of the link to launch the embedding interface.\x3Cbr\x3E\x3Cbr\x3E\n\
# Browse to the image you\'d like to embed.\x3Cbr\x3E\x3Cbr\x3E\n\
# Click the *Embed* button. You\'ll be taken to the *Image::NAME* page with your image embedded in it.\x3Cbr\x3E\x3Cbr\x3E\n\
\n\
== Use an embedded image\n\
Once an image is embedded, you can use the same include link you used to add the embedded image to include the image anywhere in the wiki. \n\
# Create a new page or open an existing page in the editor by clicking the *Edit* icon in the navigation bar.\x3Cbr\x3E\x3Cbr\x3E\n\
# Create an include link for an already embedded image. There are two ways you can do this:\x3Cbr\x3E\x3Cbr\x3E\n\
## Use this code wherever you like in a page:\x3Cpre\x3E[\\\n\
[In\\\n\
clude::Image::N\\\n\
AME]\\\n\
]\x3C/pre\x3E\n\
## Or click the editor\'s *Image* button and type in the name of the image.\x3Cbr\x3E\x3Cbr\x3E\n\
# Click the *Save* icon in the navigation bar to save the page. The image should now be where the include link was.\n\
\n\
== Use a data:URI image\n\
\n\
It is always better and advisable to embed an image instead of using a data:URI image, mostly because embedded images can be reused inside the wiki and do not garble the edit window when editing the page.\n\
\n\
However if you want to use anyway a data:URI image you can do it by directly adding the XHTML snippet:\n\
\n\
{{{\x3Cimg src="data:image/EXTENSION;ENCODING,ENCODED_IMAGE" /\x3E}}}\n\
\n\
\x3Cdiv class="woas_help_text"\x3EExample:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Cimg src="" /\x3E\n\
}}}\n\
\x3Cdiv class="woas_helptext"\x3EResult:\x3C/div\x3E\x3Cimg src="" /\x3E\n\
\n\
A famous online service to create such URIs is [[http://software.hixie.ch/utilities/cgi/data/data|The data: URI kitchen]]. The recommended encoding to be used in WoaS is base64.\n\
\n\
== Create a data:URI image button\n\
\x3Cdiv class="woas_helptext"\x3EUse this code in a page, replacing YOUR_MESSAGE with the message to be displayed and DATA_URI_GOES_HERE with the data:URI of your image:\x3C/div\x3E\x3Cbr\x3E{{{\x3Cinput type="image" onclick=\'alert("YOUR_MESSAGE")\' src="DATA_URI_GOES_HERE"\x3E}}}\n\
\n\
* \x3Cdiv class="woas_helptext"\x3EUse this example code:\x3C/div\x3E\x3Cbr\x3E{{{\n\
\x3Cinput type="image" onclick=\'alert("Hello world!")\' src="" /\x3E\n\
}}}\x3Cbr\x3E\x3Cdiv class="woas_helptext"\x3ETo create this:\x3C/div\x3E\x3Cinput type="image" onclick=\'alert("Hello world!")\' src="" /\x3E\n\
',
'= Importing full WoaS\n\
A WoaS .html file from an older version or a current version can always be imported into your WoaS.\n\
\n\
[[Include::WoaS::Template::Info|To import WoaS \x3C 0.9.6B you will need a WoaS 0.11.x release]]\n\
\n\
== Import wiki\n\
An older Wiki on a Stick can be imported into the current wiki by using the [[Special::Import]] page\n\
# Access [[Special::Import]] directly or either from [[Special::Advanced#Maintenance]]\n\
# Click the *Browse* button and select the wiki you\'d like to import\n\
# Choose the settings you\'d like to use.\x3Cbr\x3E\x3Cbr\x3E[[Include::WoaS::Template::Info|If you are importing WoaS \x3C 0.12.0 it is much better to import CSS manually and not automatically because CSS definitions have changed]]\x3Cbr\x3E\n\
# Click the *Import* button.\x3Cbr\x3E\x3Cbr\x3E\n\
# A warning will pop up letting you know that this will overwrite pages with the same title and asking if you\'re sure.\x3Cbr\x3E\x3Cbr\x3E\n\
# Click the *OK* button if you\'re sure. Otherwise, click the *Cancel* button.\n\
\n\
== Importing WSIF\n\
This method is used to import pages that have been exported using the WSIF format (see the [[WoaS::Help::WSIF]] page for more information).\n\
\n\
# Access [[Special::ImportWSIF]] directly or either from [[Special::Advanced#Maintenance]]\n\
# Click the *Browse* button and select the .wsif file to import\n\
# Choose the options to use\n\
# Click the *Import WSIF* button\n\
',
'\x3Cinput style="font-size:10px;" id="menu_string_to_search" type="text" size="12" onkeydown="return menu_key_hook(event)" onfocus="menu_search_focus(true)" onblur="menu_search_focus(false)" /\x3E&nbsp;\x3Cinput style="font-size: 10px;" class="woas_button" type="button" value="Search" onclick="menu_do_search()" /\x3E',
'= Exporting into XHTML static pages\n\
Your WoaS pages can be exported into web-compatible XHTML, CSS and eventually attachment files/images; generated pages do not use JavaScript for rendering and can be efficiently cached by webservers.\n\
\n\
# Access [[Special::Export]] directly or either from [[Special::Advanced#Maintenance]]\n\
# Modify the export directories if necessary\n\
# Choose the settings for the export.\x3Cbr\x3E\x3Cbr\x3E[[Include::WoaS::Template::Info|Note that the "Run before exporting but do not export the javascript" option means that JavaScript is run and then the XHTML is exported, but the JavaScript source code itself is not. This is useful if you have JavaScript that does custom parsing.]]\x3Cbr\x3E\n\
# Click the *Export XHTML* button. A confirmation will pop up\n\
\n\
== Exporting into WSIF\n\
# Access [[Special::ExportWSIF]] directly or iether from [[Special::Advanced#Maintenance]]\n\
# Modify the export directory if necessary\n\
# Choose the settings for the export.\x3Cbr\x3E\x3Cbr\x3E[[Include::WoaS::Template::Info|Note that you can export into a single WSIF file or multiple WSIF files. Embedded files are exported as individual files unless you choose not to export them as external file blobs, in which case they\'ll be embedded in the WSIF file(s).]]\x3Cbr\x3E\n\
# Click the *Export WSIF* button. A confirmation will pop up, telling you how many pages were exported\n\
\n\
The WSIF file(s) in the export directory can now be copied, shared, or stored for backup purposes. See also [[WoaS::Help::WSIF]].\n\
',
'\x3Cbig style="color:lime"\x3E%1 had a little %2\x3C/big\x3E',
'= Transclusion\n\
Transclusion is a special way of [[WoaS::Help::Include wiki page|including a wiki page]] in another wiki page. Instead of just displaying the contents of the included page as is, you can change how the content is displayed depending on how you write the link.\n\
\n\
This method requires that you create a page to be used as a template. This page must contain variables represented by %1, %2, %3, and so on.\n\
\n\
You can then create a transclusion link or links to that page by creating a normal include link with the values for the variables added after the page name. Each value must be preceded by a pipe ({{{|value}}}). The values you define in the link will be used from left to right to replace the numbered variables on the page you\'re including.\n\
\n\
\x3Cdiv class="helptext"\x3EUse this code, replacing PAGENAME with the name of the page to be included, and VALUE1 and VALUE2 with the values you\'d like the two variables to have when the included page is displayed:\x3C/div\x3E\n\
\x3Cdiv class="helpcode"\x3E[\x3C!-- --\x3E[Include::PAGENAME|VALUE1|VALUE2|VALUE3]\x3C!-- --\x3E]\x3C/div\x3E\n\
== Examples\n\
These examples use the [[WoaS::Template::Example::Transclusion]] page which contains two variables. The contents of that page are:\n\
\n\
{{{\n\
\x3Cbig style="color:lime"\x3E%1 had a little %2\x3C/big\x3E\n\
}}}\n\
\n\
\x3Cdiv class="helptext"\x3EUse this code:\x3C/div\x3E\n\
\x3Cdiv class="helpcode"\x3E[\x3C!-- --\x3E[Include::WoaS::Template::Example::Transclusion|Mary|lamb]\x3C!-- --\x3E]\x3C/div\x3E\n\
\x3Cdiv class="helptext"\x3ETo create this:\x3C/div\x3E\n\
[[Include::WoaS::Template::Example::Transclusion|Mary|lamb]]\n\
\n\
\x3Cdiv class="helptext"\x3EOr use this code:\x3C/div\x3E\n\
\x3Cdiv class="helpcode"\x3E[\x3C!-- --\x3E[Include::WoaS::Template::Example::Transclusion|Fred|snack]\x3C!-- --\x3E]\x3C/div\x3E\n\
\x3Cdiv class="helptext"\x3ETo create this:\x3C/div\x3E\n\
[[Include::WoaS::Template::Example::Transclusion|Fred|snack]]\n\
\n\
\x3Cdiv class="helptext"\x3EOr use this code:\x3C/div\x3E\n\
\x3Cdiv class="helpcode"\x3E[\x3C!-- --\x3E[Include::WoaS::Template::Example::Transclusion|Bob|Jane|Jack]\x3C!-- --\x3E]\x3C/div\x3E\n\
\x3Cdiv class="helptext"\x3ETo create this:\x3C/div\x3E\n\
[[Include::WoaS::Template::Example::Transclusion|Bob|Jane|Jack]]\n\
== Wiki and HTML code in transclusion\n\
Some wiki code and HTML tags are accepted in the values.\n\
\n\
\x3Cdiv class="helptext"\x3EUse this code:\x3C/div\x3E\n\
\x3Cdiv class="helpcode"\x3E[\x3C!-- --\x3E[Include::WoaS::Template::Example::Transclusion|&#042;Mary&#042;|&#042;lamb&#042;.&lt;br&gt;&lt;br&gt;Its &#047;fleece&#047; was white as &#095;snow&#095;.]\x3C!-- --\x3E]\x3C/div\x3E\n\
\x3Cdiv class="helptext"\x3ETo create this:\x3C/div\x3E\n\
[[Include::WoaS::Template::Example::Transclusion|*Mary*|*lamb*.\x3Cbr\x3E\x3Cbr\x3EIts /fleece/ was white as _snow_.]]\n\
\n\
== Infinite recursion\n\
Infinite recursion happens when you create an include link to the current page or to another page that that has an include link to the current page. The included page will be repeated multiple times followed by the include link itself being displayed in bold red text surrounded by infinity symbols like this:\n\
\n\
\x3Cfont color="red"\x3E*{{{\u221e [[Include::PAGENAME]] \u221e}}}*\x3C/font\x3E\n\
\n\
You should always prevent infinite recursions from happening.',
'[[Include::WoaS::Help::WSIF]]\n\
',
'= Importing WSIF files\n\
The [[Special::ImportWSIF]] page allows to import a [[WoaS::Help::WSIF|WSIF]] file which contains one or more wiki pages; wiki pages imported into the *WoaS::* namespace will offer special features.\n\
== Existing pages\n\
Availabe options for imported pages whose title collides with existing page titles:\n\
* *Erase all user pages before import process*\n\
* *Ignore* - do not import colliding pages\n\
* *Overwrite* - replace existing page with imported page\n\
* *Ask before overwrite* - ask for each colliding page before replacing\n\
== Security\n\
General JavaScript security options to prevent possibly malicious code from being imported.\n\
* *Comment JavaScript tags*: convert all {{{\x3Cscript ...\x3E...\x3C/script\x3E}}} tags to {{{\x3Cdisabled_script ...\x3E...\x3C/disabled_script\x3E}}}\n\
* *Comment macro definition/call*: comment all macro definitions/calls {{{\x3C\x3C\x3C...\x3E\x3E\x3E}}} so that they are not parsed/called\n\
* *Import pages of the WoaS:: namespace*: allow importing hotkeys, plugins, aliases and custom CSS\n\
\n\
*Note:* if you have enabled some JavaScript code by mistake you should enable *safe mode* in [[Special::Options]]',
'; Hotkeys\n\
$SAVE              s\n\
$EDIT              e\n\
$PRINT             p\n\
$HELP              h\n\
$GOTO              g\n\
\n\
; Key bindings\n\
; Cancel key is by default escape (ASCII 0x1b)\n\
$CANCEL            0x1b\n\
; Back key is by default backspace (ASCII 0x8)\n\
$BACK              0x8\n\
\n\
; Custom hotkeys\n\
; You can define custom hotkeys here and the associated JavaScript function\n\
; in a plugin\n\
; $CUSTOM(home)    m',
'/* BODY */\n\
body {\n\
	font-family: Georgia, verdana;\n\
}\n\
.woas_background {\n\
	background-color: #F0F0F5;\n\
}\n\
\n\
/* BUTTONS */\n\
.woas_button {\n\
	background-color: #F0F0F5;\n\
	border: 1pt solid grey;\n\
	color: darkblue;\n\
	cursor: pointer;\n\
	font-variant: normal;\n\
	margin-top: 0.438em;\n\
	text-align: center;\n\
}\n\
.woas_button:hover {\n\
	background-color: darkgrey;\n\
}\n\
\n\
/* DEBUG CONSOLE */\n\
#woas_debug_button {\n\
	margin-top: 0.5%;\n\
}\n\
#woas_debug_console_title {\n\
	color: white;\n\
	font-weight: bold;\n\
	text-align: left;\n\
}\n\
#woas_debug_log {\n\
	background-color: #F0F0F5;\n\
	border: 1px solid black;\n\
	margin-top: 0.5%;\n\
	width: 100%;\n\
}\n\
#woas_debug_log_clear_button {\n\
	margin-top: 0.3%;\n\
	margin-bottom: 0.3%;\n\
}\n\
#woas_debug_panel {\n\
	background-color: #048db4;\n\
	border: 0;\n\
	margin-top: -0.4em;\n\
}\n\
\n\
/* EDITOR */\n\
#woas_edit_page_title{\n\
	margin-top: 2.188em;\n\
}\n\
.woas_editor_button {\n\
	margin-top: 0.063em;\n\
	margin-bottom: 0.063em;\n\
}\n\
\n\
/* EMBEDDED FILES */\n\
pre.woas_embedded {\n\
	background-color: #9E9EFF;\n\
}\n\
\n\
/* ENCRYPTION */\n\
.woas_password_desc {\n\
	background-color: #FAFAFB;\n\
	border: 2pt solid navy;\n\
	font-size: 0.8em;\n\
	margin-right: 25%;\n\
	margin-left: 25%;\n\
}\n\
#woas_pwd_mask {\n\
	font-size: large;\n\
	height: 100%;\n\
	left: 0em;\n\
	position: absolute;\n\
	text-align: center;\n\
	top: 0em;\n\
	visibility: hidden;\n\
	width: 99%;\n\
	z-index: 99;\n\
}\n\
#woas_pwd_query {/* ask password overlay */\n\
	background-color: #d6dff7;\n\
	border: 1pt solid #666666; \n\
	font-size: large;\n\
	height: 100%;\n\
	left: 0em;\n\
	padding-top: 25%;\n\
	position: absolute;\n\
	text-align: center;\n\
	top: 0em;\n\
	visibility: hidden;\n\
	width: 99%;\n\
	z-index: 100;\n\
}\n\
\n\
/* FOOTER */\n\
#woas_footer {\n\
	background-color: #048db4;\n\
	border: 1pt solid black;\n\
	font-size: 95%;\n\
	font-weight: bold;\n\
	line-height: 1em;\n\
	margin-top: 0.75em;\n\
	margin-right: 0.85em;\n\
	margin-left: 15.5%;\n\
	padding-top: 0;\n\
	padding-right: 0.5%;\n\
	padding-bottom: 0;\n\
	padding-left: 0.5%;\n\
}\n\
#woas_footer a {\n\
	color: white ! important;\n\
}\n\
#woas_go_to_top_button {\n\
	margin-bottom: -0.4em;\n\
}\n\
\n\
/* HEADERS */\n\
h1.woas_header {\n\
	font-size: 1.438em;\n\
}\n\
h2.woas_header {\n\
	font-size: 1.25em;\n\
}\n\
h3.woas_header {\n\
	font-size: 1.063em;\n\
}\n\
h4.woas_header {\n\
	font-size: 0.875em;\n\
}\n\
h5.woas_header {\n\
	font-size: 0.75em;\n\
}\n\
h6.woas_header {\n\
	font-size: 0.625em;\n\
}\n\
\n\
/* HELP PAGES */\n\
.woas_help_background {\n\
	background-attachment:fixed;\n\
	background-image: url(%2FwD%2FoL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9oDDAonCzKHvroAAAEFSURBVHja7duxDYIhFIVRIA7EKk7qKoxkb2Ns1PzfObWNuRfyAB0DAAAAAAAAAAAAAAAAAAAAAAAAAIC%2FMEtf9pxzf%2FeZvfdDAYLBV4swBd8uwhR%2BuwhT%2BO0SLOE7BQg%2FvAssa8AOYPWHd4FbtfmvIVZnhyX8xnlfAVCA8kpPHAO%2FNUReqUQKEA7fDDDcHC7hmwGEHx4gp%2BDbpwc%2FCYsfHafw2%2FcG2beAevCpHeDT1V%2B6LfQWEA5fAeLhKwAKoAAAAOR4DRzt3wl6DYyXwGtgvAQeg%2BIlcBEUpwAKgALgHsAg6BTgHsAO0CyBfwwDAAAAAAAAAAAAAAAAAAAAAAAAAAAAv%2FIER4Nn%2B7YDG3wAAAAASUVORK5CYII%3D);\n\
}\n\
.woas_help_button {\n\
	font-size: 1em;\n\
	margin-top: 0.75em;\n\
	position: fixed;\n\
	right: 0.625em;\n\
	top: 0.188em;\n\
}\n\
.woas_helpcode {\n\
	font-family: monospace;\n\
	padding: 0.438em;\n\
}\n\
.woas_helptext {\n\
	font-family: lucida;\n\
}\n\
\n\
/* HOTKEYS */\n\
#woas_custom_accesskeys {\n\
	display: none;\n\
	visibility: hidden;\n\
}\n\
\n\
/* LAST MODIFIED LINE */\n\
.woas_page_mts {\n\
	font-size: small;\n\
	margin-top: 0.75em;\n\
	margin-right: 0.80em;\n\
	margin-left: 15.5%;\n\
	z-index: 0;\n\
}\n\
\n\
/* LINK - CURSOR */\n\
a {\n\
	cursor: pointer;\n\
}\n\
\n\
/* LINK - EXISTENT */\n\
a.woas_link {\n\
	color: blue;\n\
}\n\
a.woas_link:hover {\n\
	text-decoration: underline;\n\
}\n\
\n\
/* LINK - EXTERNAL */\n\
a.woas_world_link {\n\
	color: darkgreen;\n\
	text-decoration: underline;\n\
}\n\
\n\
/* LINK - NONEXISTENT */\n\
a.woas_unlink {\n\
	color: red;\n\
}\n\
a.woas_unlink:hover {\n\
	text-decoration: underline;\n\
}\n\
\n\
/* MAIN TEXT AREA */\n\
div.woas_text_area {/* any text area div */\n\
	background-color: white;\n\
	border: 1pt solid black;\n\
	padding: 0.475em;\n\
}\n\
#woas_wiki_area {/* main text area */\n\
	left: 15.5%;\n\
	margin-top: 1.313em;\n\
	margin-bottom: 0.75em;\n\
	position: relative;\n\
	text-align: justify;\n\
	width: 82.3%;\n\
	z-index: 0;\n\
}\n\
#woas_wiki_area ol li {\n\
	margin-left: -0.5em;\n\
}\n\
#woas_wiki_area ul li {\n\
	margin-left: -0.7em;\n\
}\n\
\n\
/* MAIN WIKI PANE WHEN LOCKED */\n\
.woas_text_area.locked, #woas_pwd_mask {\n\
	background-color: #eeeeee;\n\
	background-image: url(%2BTNUAAAAAHdElNRQfXAx0JNByGxueSAAAACXBIWXMAAAsSAAALEgHS3X78AAAABGdBTUEAALGPC%2FxhBQAAABlJREFUeNpj%2FM%2FwmYHpMwMvAxOQwcvECyQBO1oE%2BlG5iisAAAAASUVORK5CYII%3D);\n\
}\n\
\n\
/* MENU */\n\
#i_woas_menu_area {\n\
	background-color: white;\n\
	border: 1pt solid grey;\n\
	font-size: 0.75em;\n\
	left: 1%;\n\
	padding: 0.499em;\n\
	width: 13.2%;\n\
}\n\
#woas_menu_area ol li, #woas_ns_menu_area ol li {\n\
	margin-left: -1.55em;\n\
}\n\
#woas_menu_area ul li, #woas_ns_menu_area ul li {\n\
	margin-left: -1.85em;\n\
}\n\
.woas_menu_button {\n\
	margin-top: 0.438em;\n\
	width: 100%;\n\
}\n\
\n\
/* NAVIGATION BAR */\n\
#woas_wiki_header {\n\
	border: 1pt solid #aaa;\n\
	left: 0em;\n\
	opacity: .65;\n\
	padding-right: 0.75em;\n\
	top: 0em;\n\
	width: 99%;\n\
	z-index: 1;\n\
}\n\
#woas_title {\n\
	display: inline;\n\
	font-size: 2em;\n\
	font-weight: bold;\n\
	margin-top: 0em;\n\
	margin-bottom: 0em;\n\
	text-shadow: #888 0.13em 0.13em 0.065em;\n\
}\n\
\n\
/* NOWIKI TEXT */\n\
.woas_nowiki {\n\
	background-color: #F5F5F5;\n\
	white-space: pre-wrap; /* CSS 3 */\n\
	padding-right: 0.27em;\n\
	padding-left: 0.27em;\n\
}\n\
.woas_nowiki_multiline {\n\
	border: 0.063em solid grey;\n\
	padding-left: 0.4em;\n\
}\n\
\n\
/* PAGE LISTING HEADER */\n\
.woas_listing_options {\n\
	background-color: #AACCBB;\n\
	border: 0.1em solid blue;\n\
	padding: 0.2em;\n\
}\n\
\n\
/* SEARCH */\n\
pre.woas_search_results {\n\
	background-color: #f9f9f9;\n\
	border: 1pt solid #aaa;\n\
	clear: both;\n\
	padding: 0.313em;\n\
	margin-top: 1em;\n\
}\n\
.woas_search_highlight {\n\
	background-color: yellow;\n\
}\n\
\n\
/* TABLE OF CONTENTS */\n\
div.woas_toc {\n\
	border: 1pt dashed #aaa;\n\
	background-color: #f9f9f9;\n\
	padding: 0.313em;\n\
	width: 50%;\n\
	font-size: 95%;\n\
}\n\
div.woas_toc ol, li {\n\
	margin-left: 3.3em;\n\
	padding-left: 0em;\n\
}\n\
p.woas_toc_title {\n\
	font-weight: bold;\n\
	text-align: center;\n\
}\n\
\n\
/* TABLES */\n\
table.woas_text_area {\n\
	border: 1pt solid black;\n\
	border-spacing: 0em;\n\
}\n\
table.woas_text_area td {\n\
	border: 1pt solid;\n\
	padding: 0.313em;\n\
}\n\
table.woas_text_area caption {\n\
	font-style: italic;\n\
	font-weight: bold;\n\
}\n\
\n\
/* TAG - CONTAINER */\n\
div.woas_taglinks {\n\
	border: 1pt solid #aaa;\n\
	margin-top: 1em;\n\
	overflow: auto;\n\
	padding: 0.313em;\n\
}\n\
\n\
/* TAG - LINKS */\n\
div.woas_taglinks \x3E a {\n\
	background-color: gainsboro;\n\
	border: 2px solid blue;\n\
	/* border-radius: 7px; */\n\
	color: navy;\n\
	font-size: 90%;\n\
	font-weight: bold;\n\
	line-height: 2.4;\n\
	margin: 2px 2px 2px 0;\n\
	-moz-border-radius: 7px;\n\
	padding: 3px 5px 3px 5px;\n\
	text-decoration: none;\n\
	-webkit-border-radius: 7px;\n\
}\n\
div.woas_taglinks \x3E a:hover {\n\
	background-color: grey;\n\
	border: 2px solid blue;\n\
	color: white;\n\
	text-decoration: none;\n\
	font-weight: bold;\n\
}\n\
\n\
/* WIKI CORE PAGES */\n\
.woas_core_page {\n\
	background-color: #bbccff;\n\
}\n\
\n\
/* WIKI LOADING OVERLAY */\n\
#loading_overlay {\n\
	background-color: white;\n\
	font-size: large;\n\
	height: 100%;\n\
	left: 0em;\n\
	padding-top: 25%;\n\
	position: absolute;\n\
	text-align: center;\n\
	top: 0em;\n\
	width: 99%;\n\
	z-index: 100;\n\
}\n\
\n\
/* WIKI WAIT TEXT */\n\
.woas_wait_text {\n\
	color: navy;\n\
}',
'/* Your CSS customization goes here */',
'/* CSS used when loading/saving WoaS - readonly */\n\
body {\n\
	font-family: Georgia, verdana;\n\
}\n\
\n\
#woas_custom_accesskeys {\n\
	visibility: hidden;\n\
	display: none;\n\
}\n\
\n\
#woas_wiki_area {\n\
	position: relative;\n\
	left: 15.5%;\n\
	width: 82.3%;\n\
	z-index: 0;\n\
	margin-top: 1.313em;\n\
	margin-bottom: 0.75em;\n\
	text-align:justify;\n\
}\n\
\n\
#woas_wiki_header {\n\
	top: 0em;\n\
	left: 0em;\n\
	border: 1pt solid #aaa;\n\
	opacity:.65;\n\
	z-index: 1;\n\
	width: 99%;\n\
	padding-right:0.75em;\n\
}\n\
\n\
#loading_overlay {\n\
	position: absolute;\n\
	width: 99%;\n\
	height: 100%;\n\
	padding-top: 25%;\n\
	z-index: 100;\n\
	background-color: white;\n\
	left: 0em;\n\
	top: 0em;\n\
	font-size: large;\n\
	text-align: center;\n\
}\n\
\n\
.woas_wait_text {\n\
	color: navy;\n\
}\n\
\n\
.woas_background, #woas_debug_panel, #woas_debug_console, #woas_debug_log,\n\
#woas_edit_page_title, .woas_editor_button, #woas_pwd_query, #woas_pwd_mask,\n\
.woas_password_desc,.woas_about_footer,.woas_help_background,.woas_help_button,\n\
.woas_helpcode,.woas_helptext, .woas_page_mts, div.woas_text_area, .woas_text_area.locked,\n\
#woas_pwd_mask,.woas_core_page,div.menu,#woas_menu_area,.woas_menu_button,#woas_title,\n\
.woas_nowiki, .woas_nowiki_multiline,pre.woas_search_results,div.woas_toc,p.woas_toc_title,\n\
table.woas_text_area,div.woas_taglinks { }',
'= Hotkeys and access keys\n\
\n\
You can define key bindings for hotkeys and access keys by editing the [[WoaS::Hotkeys]] page.\n\
\n\
Example:\n\
\n\
{{{$SAVE s\n\
$EDIT e\n\
}}}\n\
\n\
The *$SAVE* and *$EDIT* definitions identify a WoaS action, while the /\'s\'/ and /\'e\'/ characters identify the associated hotkey.\n\
\n\
See also [[http://en.wikipedia.org/wiki/Access_keys]].\n\
\n\
== Custom hotkeys\n\
\n\
You can create a custom hotkey associated to a JavaScript function to be called when that hotkey is activated.\n\
\n\
Example:\n\
\n\
{{{$CUSTOM(myfunction)     k}}}\n\
\n\
The /myfunction/ JavaScript function will be called (without arguments) when the /\'k\'/ hotkey is activated.',
'= Plugins\n\
\n\
All pages of the *WoaS::Plugins::* namespace are WoaS plugins; plugins are executed when loading WoaS and remain active during WoaS usage.\n\
\n\
You can share WoaS plugins as WSIF files by exporting them.\n\
\n\
== External plugins\n\
\n\
A WoaS plugin is just JavaScript code, unless you create a plugin whose name starts with \'@\'. Such plugins are made up of external file references and a specific notation to force browser into a specific inclusion mode.\n\
\n\
Example:\n\
{{{path/to/mylib1.js = +*\n\
path/to/mylib2.js = @*}}}\n\
\n\
The first resource, {{{path/to/mylib1.js}}}, will be included as an inline JavaScript (e.g. like source code inside a {{{\x3Cscript /\x3E}}} tag), while the second, {{{path/to/mylib2.js}}}, will be included as external ({{{\x3Cscript /\x3E}}} tag with proper \'src\' attribute).\n\
\n\
=== Inclusion operators\n\
\n\
There are two inclusion operators which are valid for resource definitions:\n\
\n\
* *+* - which leads to inline inclusion\n\
* *@* - which leads to external inclusion\n\
\n\
The word which directly follows such inclusion operator can be any of the following supported tokens:\n\
\n\
* *{{{*}}}* catch-all, which means any browser/engine\n\
* *ie* Internet Explorer\n\
* *firefox* Mozilla Firefox (-)\n\
* *opera* Opera Internet Explorer\n\
* *safari* Apple Safari (-)\n\
* *chrome* Google Chrome\n\
* *gecko* Gecko engine (Mozilla)\n\
* *webkit* WebKit engine (Safari/Chrome)\n\
* *presto* Presto engine (Opera)\n\
* *trident* Trident engine (Internet Explorer)\n\
\n\
*Note: * tokens marked with (-) do not support version matching\n\
\n\
Now let\'s consider a more complex example:\n\
\n\
{{{path/to/mylib1.js = +* @gecko(1.9+)\n\
path/to/mylib2.js = @*}}}\n\
\n\
{{{path/to/mylib1.js}}} will be loaded as inline for all browsers except those which have a Gecko engine with version 1.9 or above (i.e. Firefox 3.6 and above).',
'= Aliases\n\
\n\
Aliases are replaceable shortcuts used in wiki links.\n\
\n\
*Example:*\n\
\n\
{{{[[$JD::Bio]]}}}\n\
\n\
Where /$JD/ is defined as:\n\
{{{$JD    John Doe}}}\n\
\n\
Aliases can turn out to be particularly useful to shorten typing of long page names.\n\
\n\
== Add an alias\n\
\n\
In order to add an alias you should edit the [[WoaS::Aliases]] reserved page; you should add a line to the page, like the below example:\n\
\n\
{{{$JD    John Doe}}}\n\
\n\
*$JD* is the alias, which will be replaced when found in wiki page title references, and /"John Doe"/ is the text which will replace *$JD*. You can specify any part of page titles in aliases, like namespaces or page prefixes/suffixes.',
'== Existing pages\n\
\x3Clabel for="woas_import_erase"\x3E\x3Cinput type="radio" id="woas_import_erase" name="woas_import_overwrite" onclick="woas.importer.i_overwrite=0"\x3EErase all user pages before import process\x3C/label\x3E\n\
\x3Clabel for="woas_import_ignore"\x3E\x3Cinput type="radio" id="woas_import_ignore" name="woas_import_overwrite" onclick="woas.importer.i_overwrite=1" checked="checked"\x3EIgnore\x3C/label\x3E\n\
\x3Clabel for="woas_import_overwrite"\x3E\x3Cinput type="radio" id="woas_import_overwrite" name="woas_import_overwrite" onclick="woas.importer.i_overwrite=2"\x3EOverwrite\x3C/label\x3E\n\
\x3Clabel for="woas_import_ask"\x3E\x3Cinput type="radio" id="woas_import_ask" name="woas_import_overwrite" onclick="woas.importer.i_overwrite=3"\x3EAsk before overwrite\x3C/label\x3E\n\
== Security\n\
\x3Clabel for="woas_cb_import_comment_js"\x3E\x3Cinput type="checkbox" id="woas_cb_import_comment_js" checked="checked"\x3EComment JavaScript tags\x3C/label\x3E\n\
\x3Clabel for="woas_cb_import_comment_macros"\x3E\x3Cinput type="checkbox" id="woas_cb_import_comment_macros" checked="checked"\x3EComment macro definition/call\x3C/label\x3E\n\
\x3Clabel for="woas_cb_import_woas_ns"\x3E\x3Cinput type="checkbox" id="woas_cb_import_woas_ns" checked="checked"\x3EImport pages of the [[WoaS::]] namespace ([[WoaS::Hotkeys|hotkeys]], [[WoaS::Plugins|plugins]], [[WoaS::Aliases|aliases]] and [[WoaS::CSS::Custom|custom CSS]])\x3C/label\x3E',
'= old main menu\n\
\n\
\n\
* [[WoaS History]]\n\
\n\
* [[WoaS::Help::]]\n\
* [[WoaS::Aliases]]\n\
* [[WoaS::Hotkeys]]\n\
* [[WoaS::Plugins]]\n\
\n\
* [[Special::All Pages]]\n\
* [[Special::Erase Wiki]]\n\
* [[Special::Recentchanges|Recentchanges]]\n\
* [[Special::Backlinks|Backlinks]]\n\
* [[Special::New Page|New Page]]\n\
* [[Special::Duplicate Page|Duplicate Page]]\n\
* [[Special::Delete Page|Delete Page]]\n\
* [[Special::Go to|Go to...]]\n\
',
'= Boek Trust Soap\n\
\n\
== [[About WSDL/SOAP]]\n\
\n\
* The Java Enterprise Web/Rest/Soap server runs on the [[http://code.google.com/appengine/|Google App Engine]].\n\
\n\
== On the server\n\
\n\
* For testing purposes the SVN has temporarily been forked and the code runs on a separate engine, see [[https://soaponix.appspot.com/]]\n\
* Technical details about the GAE  can be seen at [[https://soaponix.appspot.com/tech.jsp]]\n\
\n\
== For the client\n\
\n\
* To start with a simple demo, for example a client of Boektrust runs a webserver on linux, say with apache2, php5 on ubuntu. He/she wants to integrate the search capabilities of the Boek Soap server in that website.\n\
* So at first make sure that the webserver is up and running, in my case get a response at [[http://localhost]]\n\
* There are too many to set up a webserver to cover here, just make sure it executes php, for example the [[http://localhost/frans/phpinfo.php]] page, a oneliner {{{\n\
\x3C?php phpinfo(); ?\x3E \n\
}}}\n\
* Now, get the demo PHP SOAP client {{{\n\
wget https://boektrust-soep-gae.googlecode.com/svn/onixsoap/onixsoap/php/hello.php\n\
wget https://boektrust-soep-gae.googlecode.com/svn/onixsoap/onixsoap/php/BrowseWsdlService.php\n\
}}}\n\
* and have a look at [[http://localhost/frans/hello.php]]\n\
* Please note this is just a demo, not the real thing.\n\
\n\
== Explanation of the demo PHP SOAP client. \n\
\n\
* Start by looking in the source code. The hello.php is a simple html form with fields for search minimum and maximum boundaries for auteur, titel and isbn. The limit and offset are for paginating.\n\
* Please note that the demo data is all fake...\n\
* The values are grouped in a searchBooks object {{{\n\
//send request to server and retrieve response:\n\
$ret = $hello-\x3EsearchBooks($search);\n\
}}}\n\
* that function does all the hard work, putting values in XML SOAP format according to the WSDL, HTTP POST it to [[http://soaponix.appspot.com/BrowseSoapServlet/]]\n\
* and receive the XML SOAP result.\n\
* And show it as HTML table. By the way: the result array changes from type if it has only 1 item.\n\
* The code for searchBooks is in BrowseWsdlService.php and is generated by a small tool, see hello.php for more details. This tool is needed only to generate WSDL/SOAP skeleton if the interface changes, for this demo the server has been frozen.\n\
\n\
== Demo standalone JAVA client\n\
\n\
* Just as for PHP there many SOAP client libraries for JAVA. This one is using axis2-adb and does the same as as the hello.php above but now as stand alone command line client :{{{\n\
wget https://boektrust-soep-gae.googlecode.com/svn/onixsoap/onixsoap/demo/demo.jar\n\
java -jar demo.jar\n\
}}}\n\
* Those libraries conflict with the ones in the Google App Engine, so they are wrapped in executable jar. If you open the jar (a jar is a special zip file) and look in the directory testonixsoap/src/nl/boektrust/btsoep/server/wsdl/ the code starts with TestWsdl2Java function main.\n\
* After retrieving the command line parameters it fills a SearchBooksE object\n\
* using stub.searchBooks() it sends the request in SOAP XML format to the server, same style as hello.php\n\
* this BrowseWsdlServiceStub is generated with {{{\n\
/home/frans/Downloads/axis2-1.6.1/bin/wsdl2java.sh -uri \'http://soaponix.appspot.com/BrowseSoapServlet/nl/boektrust/btsoep/server/wsdl/jaxws/BrowseWsdlService.wsdl\'\n\
}}}\n\
* The result is retrieved and shown with {{{\n\
                searchBooks.setSearchBooks(search);\n\
                SearchBooksResponseE resp = stub.searchBooks(searchBooks);\n\
                for (Book book : resp.getSearchBooksResponse().get_return()) {\n\
                        logger.info("book.getAuteur()=" + book.getAuteur() + "; book.getIsbn()=" + book.getIsbn()\n\
                                        + "; book.getTitel()=" + book.getTitel());\n\
                }\n\
}}}\n\
\n\
== Another demo client Hello.jsp\n\
\n\
* This JAVA Server Page is a clone of the hello.php from above, have a look at the code [[https://boektrust-soep-gae.googlecode.com/svn/onixsoap/onixsoap/war/hello.jsp|hello.jsp]]\n\
* The JSP handles search values entered in the form and uses the stub code generated by wsimport. The libraries needed for that are the same as of the SOAP server so this allows for HTTP JSP to run a SOAP client connecting to the SOAP server all an the same machine. \n\
* Unfortunately the Google App Engine frequently times out because of this server calling the same server... Running the JSP in a local Tomcat works nicely.\n\
* The stub code to handle the SOAP is generated by {{{\n\
wsimport -Xnocompile -keep -p nl.boektrust.btsoep.client.wsdl.wsimportgenerated \'http://soaponix.appspot.com/BrowseSoapServlet/nl/boektrust/btsoep/server/wsdl/jaxws/BrowseWsdlService.wsdl\'\n\
}}}\n\
\n\
== Next, the PersistentService.jsp\n\
\n\
* SOAP access to [[PersistentService]]',
'= About WSDL/SOAP\n\
\n\
* TODO more background info',
'= PersistentService\n\
\n\
== A first attempt for JSP + SOAP client + SOAP server \n\
\n\
* it starts with [[https://soaponix.appspot.com/PersistentService.jsp]], unfortunately it times out far too often. Running the same code locally it is at [[http://127.0.0.1:8888/PersistentService.jsp]]\n\
* The [[https://boektrust-soep-gae.googlecode.com/svn/onixsoap/onixsoap/war/PersistentService.jsp|PersistentService.jsp]] is using the code generated with wsimport [[https://soaponix.appspot.com/BrowseSoapServlet/nl/boektrust/btsoep/server/jaxws/PersistentServiceSoapService.wsdl]] and the same libraries as the SOAP server.\n\
* The wsimport generated code with package nl.boektrust.btsoep.wsimport.PersistentService\n\
\n\
== How it works\n\
\n\
* nl.boektrust.btsoep.server.PersistentServiceSoap wraps nl.boektrust.btsoep.client.PersistentService to SOAP server. The PersistentServiceImpl has some dependencies which makes wsgen crash, so it is wrapped inside PersistentServiceSoap instead.\n\
* The types PersistentServiceImpl and com.googlecode.objectify.Key are excluded from SOAP exposure with @WebMethod(exclude = true)\n\
* For example: wsgen generates request/reponse classes for the method public List\x3CPhysicalBookManifestation\x3E getBooksForPerson(Person p) {...} being nl.boektrust.btsoep.server.jaxws.GetBooksForPerson and ...GetBooksForPersonResponse\n\
* A SOAP request enters via nl.boektrust.btsoep.server.wsdl.BrowseSoapServlet method doPost()\n\
* All SOAP request are send nl.boektrust.btsoep.server.wsdl.BrowseSoapHandler method handleSOAPRequest(SOAPMessage request)\n\
* depending on the namespace it is handled by the corresponding handler e.g. SOAPMessage process(GetBooksForPerson getBooksForPerson)\n\
* Next it is send to nl.boektrust.btsoep.server.wsdl.BrowseAdapter method GetBooksForPersonResponse getBooksForPerson(GetBooksForPerson gbfp)\n\
* which unwrapps the request with Person p=gbfp.getArg0()\n\
* calls the real work List\x3CPhysicalBookManifestation\x3E l=service.getBooksForPerson(p), where service is the PersistentServiceImpl\n\
* wrapps the result into a SOPA-able object ret=new GetBooksForPersonResponse(), ret.setReturn(l)\n\
* end then the response object is send to the SOAP client.\n\
\n\
== The JSP client\n\
\n\
* is using the same backend libraries as the server so can be run on the server.\n\
* Perhaps handy to put those JARs into the SVN?\n\
* Although from a functional point of view that makes little sense. It can be very handy to expose the SOAP methods as JSP forms but for the performance it should be a direct call.\n\
\n\
== Other clients\n\
\n\
* Easy to test and evaluate the SOAP functionality is with [[http://www.soapui.org/]]\n\
\n\
== TODO\n\
\n\
* It looks like the interface should be cleaned up to not use Key etc. Perhaps a small rewrite to use a clean service layer with DTOs.\n\
* One by one program all SOAP functions to end up in a small demo JSP, using a form + SOAP client + SOAP server, the same way as above.\n\
* The performance should be checked, the SOAP code gives a warning in the log EXPENSIVE METHOD ALERT: getAllPersons\n\
\n\
== To notice\n\
\n\
* For the current version it is essential to use xalan.jar, otherwise it uses the default JAVA classes com.sun.internal.* which are not on the [[http://code.google.com/appengine/docs/java/jrewhitelist.html|whitelist]]! \n\
* Using [[http://code.google.com/p/maven-gae-plugin/|maven-gae-plugin]] would be nice but the generated eclipse project is not OK.\n\
* ERRORS can be hard to spot, for example if the SOAP server encounters an error it might send a 500 HTML error message, but the SOAP client is expecting an XML SOAP message a reports a completely different error message.\n\
* Exception can be passed via SOAP, in the JSP demo page look for a try-catch block.',
'= Test\n\
\n\
* The JUNIT test code in package nl.boektrust.btsoep.client.wsdl.wsimportgenerated.TestWsimportGenerated tests the roundtrip to the soaponix server with its functionality from WSIMPORT and WSGEN.'
];

/* DFQRCTsKlU-0000217-END */

/* ]]> */ </script>
<title woas_permanent="1">Main Page</title>
<style type="text/css" woas_permanent="1" woas_core_style="1">/* CSS used when loading/saving WoaS - readonly */
body {
	font-family: Georgia, verdana;
}

#woas_custom_accesskeys {
	visibility: hidden;
	display: none;
}

#woas_wiki_area {
	position: relative;
	left: 15.5%;
	width: 82.3%;
	z-index: 0;
	margin-top: 1.313em;
	margin-bottom: 0.75em;
	text-align:justify;
}

#woas_wiki_header {
	top: 0em;
	left: 0em;
	border: 1pt solid #aaa;
	opacity:.65;
	z-index: 1;
	width: 99%;
	padding-right:0.75em;
}

#loading_overlay {
	position: absolute;
	width: 99%;
	height: 100%;
	padding-top: 25%;
	z-index: 100;
	background-color: white;
	left: 0em;
	top: 0em;
	font-size: large;
	text-align: center;
}

.woas_wait_text {
	color: navy;
}

.woas_background, #woas_debug_panel, #woas_debug_console, #woas_debug_log,
#woas_edit_page_title, .woas_editor_button, #woas_pwd_query, #woas_pwd_mask,
.woas_password_desc,.woas_about_footer,.woas_help_background,.woas_help_button,
.woas_helpcode,.woas_helptext, .woas_page_mts, div.woas_text_area, .woas_text_area.locked,
#woas_pwd_mask,.woas_core_page,div.menu,#woas_menu_area,.woas_menu_button,#woas_title,
.woas_nowiki, .woas_nowiki_multiline,pre.woas_search_results,div.woas_toc,p.woas_toc_title,
table.woas_text_area,div.woas_taglinks { }</style>
<script woas_permanent="1" language="javascript" type="text/javascript">
/* <![CDATA[ */
/*** src/aes.js ***/
// AES encryption
// license: GNU/GPLv2
// original code from http://home.versatel.nl/MAvanEverdingen/Code/
// this is a javascript conversion of a C implementation by Mike Scott
// adapted for WoaS by legolas558
// namespace wrapping by pvhl

// namespace wrapper for woas.AES
(function() {
	
var bData = null,
	sData = null,
	aes_i = null,
	aes_j = null,
	tot = null,
	key =  [],
	wMax =  0xFFFFFFFF,
	aesNk = null,
	aesNr = null,
	aesPows = null,
	aesLogs = null,
	aesSBox = null,
	aesSBoxInv = null,
	aesRco = null,
	aesFtable = null,
	aesRtable = null,
	aesFi = null,
	aesRi = null,
	aesFkey = null,
	aesRkey = null;

function rotb(b,n){ return ( b<< n | b>>>( 8-n) ) & 0xFF; }
function rotw(w,n){ return ( w<< n | w>>>(32-n) ) & wMax; }
function getW(a,i){ return a[i]|a[i+1]<<8|a[i+2]<<16|a[i+3]<<24; }
function setW(a,i,w){ a.splice(i,4,w&0xFF,(w>>>8)&0xFF,(w>>>16)&0xFF,(w>>>24)&0xFF); }
function setWInv(a,i,w){ a.splice(i,4,(w>>>24)&0xFF,(w>>>16)&0xFF,(w>>>8)&0xFF,w&0xFF); }
function getB(x,n){ return (x>>>(n*8))&0xFF; }

function aesMult(x, y){ return (x&&y) ? aesPows[(aesLogs[x]+aesLogs[y])%255]:0; }

function aesPackBlock() {
	return [ getW(bData,aes_i), getW(bData,aes_i+4),
			getW(bData,aes_i+8), getW(bData,aes_i+12) ];
}

function aesUnpackBlock(packed){
  for ( var mj=0; mj<4; mj++,aes_i+=4) setW( bData, aes_i, packed[mj] );
}

function aesXTime(p){
  p <<= 1;
  return p&0x100 ? p^0x11B : p;
}

function aesSubByte(w){
  return aesSBox[getB(w,0)] | aesSBox[getB(w,1)]<<8 | aesSBox[getB(w,2)]<<16 | aesSBox[getB(w,3)]<<24;
}

function aesProduct(w1,w2){
  return aesMult(getB(w1,0),getB(w2,0)) ^ aesMult(getB(w1,1),getB(w2,1))
       ^ aesMult(getB(w1,2),getB(w2,2)) ^ aesMult(getB(w1,3),getB(w2,3));
}

function aesInvMixCol(x){
  return aesProduct(0x090d0b0e,x)     | aesProduct(0x0d0b0e09,x)<<8 |
         aesProduct(0x0b0e090d,x)<<16 | aesProduct(0x0e090d0b,x)<<24;
}

function aesByteSub(x){
  var y=aesPows[255-aesLogs[x]];
  x=y;  x=rotb(x,1);
  y^=x; x=rotb(x,1);
  y^=x; x=rotb(x,1);
  y^=x; x=rotb(x,1);
  return x^y^0x63;
}

// Generate static tables
(function(){
  var i,j,m,y;
  aesPows = [ 1,3 ];
  aesLogs = [ 0,0,null,1 ];
  aesSBox = new Array(256);
  aesSBoxInv = new Array(256);
  aesFtable = new Array(256);
  aesRtable = new Array(256);
  aesRco = new Array(30);

  for ( i=2; i < 256; i++){
    aesPows[i]=aesPows[i-1]^aesXTime( aesPows[i-1] );
    aesLogs[aesPows[i]]=i;
  }

  aesSBox[0]=0x63;
  aesSBoxInv[0x63]=0;
  for ( i=1; i < 256; i++){
    y=aesByteSub(i);
    aesSBox[i]=y; aesSBoxInv[y]=i;
  }

  for (i=0,y=1; i < 30; i++){ aesRco[i]=y; y=aesXTime(y); }

  for ( i=0; i < 256; i++){
    y = aesSBox[i];
    aesFtable[i] = aesXTime(y) | y<<8 | y<<16 | (y^aesXTime(y))<<24;
    y = aesSBoxInv[i];
    aesRtable[i]= aesMult(14,y) | aesMult(9,y)<<8 |
                  aesMult(13,y)<<16 | aesMult(11,y)<<24;
  }

  aesFi = new Array(12);
  aesRi = new Array(12);

  for (m=j=0;j<4;j++,m+=3){
    aesFi[m]=(j+1)%4;
    aesFi[m+1]=(j+2)%4;
    aesFi[m+2]=(j+3)%4;
    aesRi[m]=(4+j-1)%4;
    aesRi[m+1]=(4+j-2)%4;
    aesRi[m+2]=(4+j-3)%4;
  }

})();

function aesInit(){
  key=key.slice(0,43);
  var i,k;
  var j = 0;
  var l = key.length;

  while ( l!=16 && l!=24 && l!=32 && l!=43) key[l++]=key[j++];

  aesNk = key.length >>> 2;
  aesNr = 6 + aesNk;

  var N=4*(aesNr+1);
  aesFkey = new Array(N);
  aesRkey = new Array(N);

  for (i=j=0;i< aesNk;i++,j+=4) aesFkey[i]=getW(key,j);

  for (k=0,j=aesNk;j < N;j+=aesNk,k++){
    aesFkey[j]=aesFkey[j-aesNk]^aesSubByte(rotw(aesFkey[j-1], 24))^aesRco[k];
    if (aesNk<=6)
      for (i=1;i < aesNk && (i+j) < N;i++) aesFkey[i+j]=aesFkey[i+j-aesNk]^aesFkey[i+j-1];
    else{
      for (i=1;i<4 &&(i+j) < N;i++) aesFkey[i+j]=aesFkey[i+j-aesNk]^aesFkey[i+j-1];
      if ((j+4) < N) aesFkey[j+4]=aesFkey[j+4-aesNk]^aesSubByte(aesFkey[j+3]);
      for (i=5;i < aesNk && (i+j) < N;i++) aesFkey[i+j]=aesFkey[i+j-aesNk]^aesFkey[i+j-1];
    }
  }

  for (j=0;j<4;j++) aesRkey[j+N-4]=aesFkey[j];
  for (i=4;i < N-4;i+=4){
    k=N-4-i;
    for (j=0;j < 4;j++) aesRkey[k+j]=aesInvMixCol(aesFkey[i+j]);
  }
  for (j=N-4;j < N;j++) aesRkey[j-N+4]=aesFkey[j];
}

function aesClose(){
  aesFkey=aesRkey=null;
}

function aesRounds( block, key, table, inc, box ){
  var tmp = new Array( 4 );
  var i,j,m,r;

  for ( r=0; r<4; r++ ) block[r]^=key[r];
  for ( i=1; i < aesNr; i++ ){
    for (j=m=0;j<4;j++,m+=3){
      tmp[j]=key[r++]^table[block[j]&0xFF]^
			rotw(table[(block[inc[m  ]] >>> 8)&0xFF], 8)^
			rotw(table[(block[inc[m+1]] >>>16)&0xFF],16)^
			rotw(table[(block[inc[m+2]] >>>24)&0xFF],24);
    }
    var t=block; block=tmp; tmp=t;
  }

  for (j=m=0;j<4;j++,m+=3)
    tmp[j]=key[r++]^box[block[j]&0xFF]^
           rotw(box[(block[inc[m  ]] >>> 8)&0xFF], 8)^
           rotw(box[(block[inc[m+1]] >>>16)&0xFF],16)^
           rotw(box[(block[inc[m+2]] >>>24)&0xFF],24);
  return tmp;
}

function _encrypt(){
  aesUnpackBlock( aesRounds(aesPackBlock(), aesFkey, aesFtable, aesFi, aesSBox ) );
}

function _decrypt(){
  aesUnpackBlock( aesRounds(aesPackBlock(), aesRkey, aesRtable, aesRi, aesSBoxInv ) );
}

// Blockcipher

function blcEncrypt(enc){
	if (tot === 0){
		if (key.length < 1) return;
		// pre-pend random data to pad length? really?
		for (aes_i=0; aes_i<16; ++aes_i) bData.unshift( _rand(256) );
		while( bData.length%16 !== 0 ) bData.push(0);
		tot = bData.length;
		aesInit();
	}else{
		for (aes_j=aes_i; aes_j < aes_i+16; aes_j++)
		bData[aes_j] ^= bData[aes_j-16];
		enc();
	}
	if (aes_i >= tot) aesClose();
}

function blcDecrypt(dec){
	// initialize length
	if (tot === 0){
		if (key.length<1) return false;
		aes_i=16;
		tot = bData.length;
		if ( (tot%16) || (tot < aes_i) ) {
			woas.log('AES: Incorrect length (tot='+tot+', aes_i='+aes_i+')'); //log:1
			return false;
		}
		aesInit();
	} else {
		aes_i=tot-aes_i;
		dec();
		for (aes_j=aes_i-16; aes_j < aes_i; aes_j++) bData[aes_j] ^= bData[aes_j-16];
		aes_i = tot+32-aes_i;
	}
	if (aes_i>=tot){
		aesClose();
		bData.splice(0,16);
		// remove 0s added for padding (supposedly!)
		while(bData[bData.length-1] === 0) bData.pop();
	}
	return true;
}

// @module aes
woas.AES = {
	// sets global key to the utf-8 encoded key (byte array)
	setKey: function(sKey) {
		key = woas.utf8.encode_to_array(sKey);
	},
	clearKey: function(){
		key = [];
	},
	// keep 'key' private to this code
	isKeySet: function(){
		return key.length > 0;
	},
	// returns an array of encrypted characters
	encrypt: function(raw_data){
		bData = woas.utf8.encode_to_array(raw_data);
		
		aes_i=tot=0;
		do{ blcEncrypt(_encrypt); } while (aes_i<tot);
		
		var rv = bData;
		bData = null;
		return rv;
	},

	// decrypts an array of encrypted characters
	decrypt: function(raw_data){
		bData = raw_data;
		
		aes_i=tot=0;
		do {
			if (!blcDecrypt(_decrypt))
				return null;
		} while (aes_i<tot);
		
		sData = woas.utf8.decode_from_array(bData);
		bData = [];
		var rv = sData;
		sData = null;
		return rv;
	}
};

})(); // end of AES closure

/*** src/framework.js ***/

woas.browser = {
	// browsers - when different from 'false' it contains the version string
	ie: false, 
	firefox: false,
	opera: false,
	safari: false,
	chrome: false,
	
	// breeds - used internally, should not be used by external plugins
	ie6: false, ie8: false,
	firefox2: false,
	firefox3: false, firefox_new: false,
					
	// engines - set to true when present
	// gecko and webkit will contain the engine version
	gecko: false, webkit: false, presto: false, trident: false
};

// used to match browser version
var m;

if((navigator.userAgent).indexOf("Opera")!=-1) {
	m = navigator.userAgent.match(/Opera\/(\S*)/);
//	if (m && m[1])
		woas.browser.opera = m[1];
} else if (navigator.userAgent.indexOf("Chrome") != -1) {
	// detect version
	m = navigator.userAgent.match(/Chrome\/([^\s]+)/);
//	if (m && m[1])
		woas.browser.chrome = m[1];
} else if (navigator.userAgent.toLowerCase().indexOf("applewebkit") != -1) {
	// Safari never publicizes its version
	woas.browser.safari = true;
} else if(navigator.appName == "Netscape") {
	// check that it is Gecko first
	woas.browser.firefox = woas.browser.gecko = (new RegExp("Gecko\\/\\d")).test(navigator.userAgent) ? true : false;
	// match also development versions of Firefox "Shiretoko" / "Namoroka"
	if (woas.browser.gecko) {
		// match the last word of userAgent
		m = navigator.userAgent.match(/rv:([^\s\)]*)/);
//		if (m && m[1]) {
			woas.browser.gecko = m[1];
			switch (woas.browser.gecko.substr(3)) {
				case "1.8":
					woas.browser.firefox2 = true;
				break;
				case "1.9":
					woas.browser.firefox3 = true;
				break;
				default:
					// possibly Firefox4
					woas.browser.firefox_new = true;
			}
	} // not Gecko
} else if((navigator.appName).indexOf("Microsoft")!=-1) {
	woas.browser.ie8 = document.documentMode ? true : false;
	if (!woas.browser.ie8)
		woas.browser.ie6 = window.XMLHttpRequest ? false : true;
	// detect version
	m = navigator.userAgent.match(/MSIE\s([^;]*)/);
//	if (m && m[1])
		woas.browser.ie = m[1];
}

// finds out if Opera is trying to look like Mozilla
if (woas.browser.firefox && (navigator.product != "Gecko")) {
	woas.browser.firefox = woas.browser.firefox2
	= woas.browser.firefox3 = woas.browser.firefox_new = false;
	if (typeof window.opera != "undefined")
		woas.browser.opera = true;
}

// finds out if Opera is trying to look like IE
if (woas.browser.ie && (typeof window.opera != "undefined")) {
	woas.browser.ie = woas.browser.ie6 = woas.browser.ie8 = false;
	woas.browser.opera = true;
}

// detect engine type
if (woas.browser.ie)
	woas.browser.trident = true;
else if (woas.browser.chrome || woas.browser.safari) {
	m = navigator.userAgent.match(/AppleWebKit\/(\S*)/);
//    if (m && m[1])
		woas.browser.webkit = m[1];
} else if (woas.browser.opera)
	woas.browser.presto = true;

var is_windows = (navigator.appVersion.toLowerCase().indexOf("windows")!=-1);

woas._server_mode = (document.location.toString().match(/^file:\/\//) ? false:true);

// set to true if we need Java-based file load/save
woas.use_java_io = woas.browser.chrome || woas.browser.opera || woas.browser.safari;

// returns the DOM element object given its id - enables a try/catch mode when debugging
if (woas.config.debug_mode) {
	// returns the DOM element object given its id, alerting if the element is not found (but that would never happen, right?)
	function d$(id){ try{return document.getElementById(id);}catch(e){woas.crash("d$('"+id+"') invalid reference:\n\n"+e);} }
} else {
	// much faster version
	function d$(id){return document.getElementById(id);}
}

d$.checked = function(id) {
	//FIXME: configuration should not be changed by reading a property!!
	woas.cfg_changed = true;
	if (d$(id).checked)
		return true;
	return false;
};

d$.hide = function(id) {
	d$(id).style.display = "none";
	d$(id).style.visibility = "hidden";
};

d$.show = function(id) {
	d$(id).style.display = "inline";
	d$(id).style.visibility = "visible";
};

d$.hide_ni = function(id) {
	d$(id).style.visibility = "hidden";
};

d$.show_ni = function(id) {
	d$(id).style.visibility = "visible";
};

d$.is_visible = function(id) {
	return !!(d$(id).style.visibility == 'visible');
};

d$.toggle = function(id) {
	if (d$.is_visible(id))
		d$.hide(id);
	else
		d$.show(id);
};

d$.clone = function(obj) {
	var nobj = {};
	for (var i in obj) {
		nobj[i] = obj[i];
	}
	return nobj;
};

// logging function has not to be in WoaS object
if (woas.config.debug_mode) {
	// logging function - used in development
	woas.log = function (aMessage) {
	    var logbox = d$("woas_debug_log");
	    // count lines
	    if (!woas.tweak.integrity_test) {
			nls = logbox.value.match(/\n/g);
			// log maximum 1024 lines
			if (nls!=null && typeof(nls)==='object' && nls.length>1024)
				logbox.value = "";
		}
		logbox.value += aMessage + "\n";
		// keep the log scrolled down
		logbox.scrollTop = logbox.scrollHeight;
		if(window.opera)
			opera.postError(aMessage);
	};
} else {
	woas.log = function(aMessage) { };
}

// fixes the Array prototype for older browsers
if (typeof Array.prototype.push == "undefined") {
  Array.prototype.push = function(str) {
    this[this.length] = str;
  };
}

// the following methods complete the Array object for non-compliant browsers
if (typeof Array.prototype.splice == "undefined") {
  Array.prototype.splice = function(offset, length) {
    var temp = [];
    for (var i = this.length - 1; i >= 0; i--) {
      if (i < offset || i > (offset + length - 1)) {
        temp[temp.length] = this[i];
      }
      this.length--;
    }
    for (i = temp.length - 1; i >= 0; i--) {
      this[this.length] = temp[i];
    }
    return this;
  };
}

if (typeof Array.prototype.indexOf == "undefined") {
	Array.prototype.indexOf = function(val, fromIndex) {
		if (typeof(fromIndex) != 'number') fromIndex = 0;
		for (var index = fromIndex,len = this.length; index < len; index++)
			if (this[index] == val) return index;
		return -1;
	};
}

// implements a custom function which returns an array with unique elements - deprecated
Array.prototype.toUnique = function() {
	var a_o = {}, new_arr = [];
	var l=this.length;
	for(var i=0; i<l;i++) {
		if (a_o[this[i]]===undefined) {
			a_o[this[i]] = true;
			new_arr.push(this[i]);
		}
	}
	if (new_arr.length!=l)
		return new_arr;
	return this;
};

// provide regex escaping
// thanks to S.Willison
RegExp.escape = function(text) {
  if (!arguments.callee.sRE) {
    var specials = ['/', '.', '*', '+', '?', '|', '$', '(', ')', '[', ']', '{', '}', "\\" ];
    arguments.callee.sRE = new RegExp(
      "(\\" + specials.join("|\\") + ')', 'g'
    );
  }
  return text.replace(arguments.callee.sRE, "\\$1");
};

// repeat string s for n times
 if (typeof String.prototype.repeat == "undefined") {
	String.prototype.repeat = function(n) {
		var r = "";
		while (--n >= 0) r += this;
		return r;
	};
}

// return a random integer given the maximum value (scale)
function _rand(scale) {
	return Math.floor(Math.random() * scale);
}

// returns a random string of given string_length
function _random_string(string_length) {
	var chars = "ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
	var randomstring = '';
	for (var i=0; i < string_length; i++) {
		var rnum = _rand(chars.length);
		randomstring += chars.charAt(rnum);
	}
	return randomstring;
}

// converts the number of bytes to a human readable form
function _convert_bytes(bytes) {
	var U=['bytes','Kb','Mb','Gb','Pb'];
	var n=0;
	bytes=Math.ceil(bytes);
	while(bytes>=1024) {
		 ++n;
		 bytes /= 1024;
	}
	return bytes.toFixed(2).replace(/\.00$/, "") +' '+ U[n];
}

// implement an sprintf() bare function
String.prototype.sprintf = function() {
	// check that arguments are OK
	if (typeof arguments == "undefined") { return null; }
	// next argument to pick
	var i_pos = 0, max_pos = arguments.length - 1;
	var fmt_args = arguments;
	return this.replace(/%[sd]/g, function(str) {
		// replace with the original unparsed token in case of undefined parameter
		if (i_pos > max_pos)
			return str;
/*		if (str == '%d')
			return Number(arguments[i_pos++]); */
		// return '%s' string
		return fmt_args[i_pos++];
	});
};

// get filename of currently open file in browser
function _get_this_filename() {
	var filename = unescape(document.location.toString().split("?")[0]);
	if (woas.browser.opera)
		filename = filename.replace(/^file:\/\/[^\/]+/, '');
	else {
		if (filename.indexOf("file://") === 0) // all browsers
			filename = filename.substr(7);
		if (filename.indexOf("///")===0) // firefox
			filename = filename.substr(1);
	}
	//TODO: check that 'g' can be removed
	filename = filename.replace(/#.*$/g, ""); // remove fragment (if any)
	if (is_windows) {
		// convert unix path to windows path
		filename = filename.replace(/\//g, "\\");
		if (filename.substr(0,2)!="\\\\") { // if this is not a network path - will be true in case of Firefox for example
			// remove leading slash before unit:
			if (filename.match(/^\\\w:\\/))
				filename = filename.substr(1);
			if (filename.charAt(1)!=':') {
				if (woas.browser.ie)
					filename = "\\\\"+filename;
			}
		}
	}
	return filename;
}

function ff_fix_focus() {
	//runtime fix for Firefox bug 374786
	if (woas.browser.firefox)
		d$("woas_wiki_area").blur();
}

if (is_windows) {
	var reFwdSlash = new RegExp("/", "g");
	woas.fix_path_separators = function(path) {
		return path.replace(reFwdSlash, woas.DIRECTORY_SEPARATOR);
	};
} else { // UNIX or similar, no path change
	woas.fix_path_separators = function(path) {
		return path;
	};
}

woas.base64 = {
	_b64arr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
	reValid: /^[A-Za-z0-9+\/=]+$/,
	
	_core_encode: function(c1, c2, c3) {
		var enc1, enc2, enc3, enc4;
		
		enc1 = c1 >> 2;
		enc2 = ((c1 & 3) << 4) | (c2 >> 4);
		enc3 = ((c2 & 15) << 2) | (c3 >> 6);
		enc4 = c3 & 63;

		if (isNaN(c2))	enc3 = enc4 = 64;
		else if (isNaN(c3))
			enc4 = 64;

		return this._b64arr.charAt(enc1) + this._b64arr.charAt(enc2) +
				this._b64arr.charAt(enc3) +	this._b64arr.charAt(enc4);
	},

	encode_array: function(input_arr) {
		var c1, c2, c3, i = 0, z = input_arr.length,output = "";
		
		do {
			c1 = input_arr[i++];
			if (i == z)
				c3 = c2 = null;
			else {
				c2 = input_arr[i++];
				if (i == z)
					c3 = null;
				else
					c3 = input_arr[i++];
			}
			output += this._core_encode(c1, c2, c3);
		} while (i < z);
		return output;
	},

	encode: function(input) {
		var c1, c2, c3, i = 0, z = input.length, output = "";
		
		do {
			c1 = input.charCodeAt(i++);
			c2 = input.charCodeAt(i++);
			c3 = input.charCodeAt(i++);
			
			output += this._core_encode(c1, c2, c3);
		} while (i < z);
		return output;
	},

	decode: function(input, z) {
		var c1, c2, c3, enc1, enc2, enc3, enc4, i = 0,
			output = "";
		
		var l=input.length;
		if (typeof z=='undefined') z = l;
		else if (z>l) z=l;

		do {
			enc1 = this._b64arr.indexOf(input.charAt(i++));
			enc2 = this._b64arr.indexOf(input.charAt(i++));
			enc3 = this._b64arr.indexOf(input.charAt(i++));
			enc4 = this._b64arr.indexOf(input.charAt(i++));

			c1 = (enc1 << 2) | (enc2 >> 4);
			c2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			c3 = ((enc3 & 3) << 6) | enc4;

			output += String.fromCharCode(c1);
			if (enc3 != 64)
				output += String.fromCharCode(c2);
			if (enc4 != 64)
				output += String.fromCharCode(c3);

		} while (i < z);

		return output;
	},

	decode_array: function(input, z) {
		var c1, c2, c3, enc1, enc2, enc3, enc4, i = 0;
		var output = [];
		
		var l=input.length;
		if (typeof z=='undefined') z = l;
		else if (z>l) z=l;

		do {
			enc1 = this._b64arr.indexOf(input.charAt(i++));
			enc2 = this._b64arr.indexOf(input.charAt(i++));
			enc3 = this._b64arr.indexOf(input.charAt(i++));
			enc4 = this._b64arr.indexOf(input.charAt(i++));

			c1 = (enc1 << 2) | (enc2 >> 4);
			c2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			c3 = ((enc3 & 3) << 6) | enc4;

			output.push(c1);
			if (enc3 != 64)
				output.push(c2);
			if (enc4 != 64)
				output.push(c3);
		} while (i < z);
		return output;
	}

};

woas.utf8 = {
	// encode from string to string
	encode: function(s) {
		return unescape( encodeURIComponent( s ) );
	},
	
	encode_to_array: function(s) {
		return woas.split_bytes( this.encode(s) );
	},
	decode: function(s) {
		return decodeURIComponent(escape(s));
	},
	decode_from_array: function(byte_arr) {
		try {
			return this.decode( woas.merge_bytes( byte_arr ) );
		}
		catch (e) {
			woas.log(e);	//log:1
		}
		return null;
	},
	
	reUTF8Space: /[^\u0000-\u007F]+/g,
	
	// convert UTF8 sequences of the XHTML source into &#dddd; sequences
	do_escape: function(src) {
		return src.replace(this.reUTF8Space, function ($1) {
			var l=$1.length;
			var s="";
			for(var i=0;i < l;i++) {
				s+="&#"+$1.charCodeAt(i)+";";
			}
			return s;
		});
	}

};

woas._last_filename = null;

woas._get_path = function(id) {
	if (this.browser.firefox3 || this.browser.firefox_new)
		return this.dirname(ff3_getPath(d$(id)));
	// use the last used path
	if (this.browser.opera)
		return this.dirname(this._last_filename);
	// on older browsers this was allowed
	return this.dirname(d$(id).value);
};

// tool to read/store flags in an integer
woas.bitfield = {
	// 32bit full mask
	_field_mask: [0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80,
				0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000,
				0x10000, 0x20000, 0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000,
				0x1000000, 0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000],
	
	get: function(bm, pos) {
		return (bm & this._field_mask[pos]) ? true : false;
	},
	
	set: function(bm, pos, value) {
		if (value)
			return bm | this._field_mask[pos];
		return bm & ~this._field_mask[pos];
	},
	
	// return an integer after having parsed given object with given order
	get_object: function(obj, order) {
		var rv=0;
		for(var i=0;i<order.length;++i) {
			if (obj[order[i]])
				rv |= this._field_mask[i];
		}
		return rv;
	},

	// set object properties to true/false after parsing the bits by given order
	set_object: function(obj, order, bm) {
		for(var i=0;i<order.length;++i) {
			obj[order[i]] = (bm & this._field_mask[i]) ? true : false;
		}
	}
};

// natural sorting algorithms by B.Huisman
// original algorithms by D.Koelle
// http://my.opera.com/GreyWyvern/blog/show.dml/1671288
woas.chunkify = function(t) {
    var tz = [], x = 0, y = -1, n = 0, i, j;

    while (i = (j = t.charAt(x++)).charCodeAt(0)) {
      var m = (i == 46 || (i >=48 && i <= 57));
      if (m !== n) {
        tz[++y] = "";
        n = m;
      }
      tz[y] += j;
    }
    return tz;
};

woas.strnatcmp = function(a, b) {
  var	aa = woas.chunkify(a),
		bb = woas.chunkify(b);

  for (x = 0; aa[x] && bb[x]; x++) {
    if (aa[x] !== bb[x]) {
      var c = Number(aa[x]), d = Number(bb[x]);
      if (c == aa[x] && d == bb[x]) {
        return c - d;
      } else return (aa[x] > bb[x]) ? 1 : -1;
    }
  }
  return aa.length - bb.length;
};

/*
Array.prototype.natsort = function(caseInsensitive) {
  for (var z = 0, t; t = this[z]; z++) {
    this[z] = [];
    var x = 0, y = -1, n = 0, i, j;

    while (i = (j = t.charAt(x++)).charCodeAt(0)) {
      var m = (i == 46 || (i >=48 && i <= 57));
      if (m !== n) {
        this[z][++y] = "";
        n = m;
      }
      this[z][y] += j;
    }
  }

  this.sort(function(a, b) {
    for (var x = 0, aa, bb; (aa = a[x]) && (bb = b[x]); x++) {
      if (caseInsensitive) {
        aa = aa.toLowerCase();
        bb = bb.toLowerCase();
      }
      if (aa !== bb) {
        var c = Number(aa), d = Number(bb);
        if (c == aa && d == bb) {
          return c - d;
        } else return (aa > bb) ? 1 : -1;
      }
    }
    return a.length - b.length;
  });

  for (var z = 0; z < this.length; z++)
    this[z] = this[z].join("");
}
*/

/*** src/loadsave.js ***/
// load modes which should be supported by load/save browser bindings
woas.file_mode = {
	UTF8_TEXT:		0,
	ASCII_TEXT:		1,
	DATA_URI:		2,
	BINARY:			3,
	BASE64:			4,
	UTF16_TEXT:		8
};

woas._guess_mime = function(filename) {
	var m=filename.match(/\.(\w+)$/);
	if (m===null) m = "";
	else m=m[1].toLowerCase();
	var guess_mime = "image";
	switch (m) {
		case "png":
		case "gif":
		case "bmp":
			guess_mime += "/"+m;
			break;
		case "jpg":
		case "jpeg":
			guess_mime = "image/jpeg";
			break;
	}
	return guess_mime;
};

// creates a DATA:URI from a plain content stream
woas._data_uri_enc = function(filename, ct, guess_mime) {
	if (typeof guess_mime != "string")
		guess_mime = this._guess_mime(filename);
	// perform base64 encoding
	return "data:"+guess_mime+";base64,"+this.base64.encode(ct);
};
woas._data_uri_enc_array = function(filename, arr, guess_mime) {
	if (typeof guess_mime != "string")
		guess_mime = this._guess_mime(filename);
	// perform base64 encoding
	return "data:"+guess_mime+";base64,"+this.base64.encode_array(arr);
};

// save the currently open WoaS
woas._save_this_file = function(new_data, old_data) {
	var filename = _get_this_filename();

	var r = woas.save_file(filename, this.file_mode.ASCII_TEXT,
		this.DOCTYPE + this.DOC_START + "<"+"script woas_permanent=\"1\" type=\"tex"+"t/javascript\">"
		+ new_data + "\n" + old_data + "<"+"/html>");
	if (r===true)
		woas.log("NOTICE: \""+filename+"\" saved successfully");	// log:1
	else {
		var msg = this.i18n.SAVE_ERROR.sprintf(filename) + "\n\n";
		if (this.use_java_io) {
			// try to understand what went bad with Java
			if (typeof document.applets.TiddlySaver == "undefined")
				msg += this.i18n.NO_TIDDLY_SAVER+" "+TIDDLY_HELP;
			else if (typeof java == "undefined")
				msg += this.i18n.NO_JAVA+" "+TIDDLY_HELP;
			else
				msg += this.i18n.UNSPECIFIED_JAVA_ERROR;
		} else
			msg += woas.i18n.UNSUPPORTED_BROWSER.sprintf(navigator.userAgent);
		this.alert(msg);
	}
	return r;
};

//API1.0: save-file handler
//NOTE: save_mode is not always enforced by browser binding
woas.save_file = function(fileUrl, save_mode, content) {
	var r = null;
	if (!this.use_java_io) {
		r = this.mozillaSaveFile(fileUrl, save_mode, content);
		if((r === null) || (r === false))
			r = this.ieSaveFile(fileUrl, save_mode, content);
		// fallback to try also with Java saving
	} else
		return this.javaSaveFile(fileUrl, save_mode, content);
	if((r === null) || (r === false))
		r = this.javaSaveFile(fileUrl, save_mode, content);
	return r;
};

var reDataUrlPfx = new RegExp("^data:\\s*([^;]*);\\s*base64,\\s*");
// get file content in FF3 without .enablePrivilege() (FBNil)
woas.mozillaLoadFileID = function(obj_id, load_mode, suggested_mime) {
	var obj = document.getElementById(obj_id);
	if(!window.Components || !obj.files)
		return null;
	var D=obj.files.item(0);
	if (D === null)
		return false;

	switch (load_mode) {
		case this.file_mode.DATA_URI:
			if (typeof suggested_mime != "string")
				return D.getAsDataURL();
			else // apply mime override
				return D.getAsDataURL().replace(/^data:(\s*)([^;]*)/, "data:$1"+suggested_mime);
			break;
		case this.file_mode.BASE64:
			return D.getAsDataURL().replace(reDataUrlPfx, '');
		case this.file_mode.BINARY:
			return D.getAsBinary();
		case this.file_mode.UTF8_TEXT:
			return D.getAsText("utf-8");
		case this.file_mode.UTF16_TEXT:
			return D.getAsText("utf-16");
		case this.file_mode.ASCII_TEXT:
			return D.getAsText("");
	}
	// not available
	this.crash(this.i18n.MODE_NOT_AVAIL.sprintf(load_mode.toString(16)));
	return null;
};

// see http://dev.w3.org/2006/webapi/FileAPI/
/*woas.ECMALoadFile = function(fileUrl, load_mode, suggested_mime) {
	if (typeof FileReaderSync == "undefined")
		return null;
	var D = new FileReaderSync();
	try {
		switch (load_mode) {
			case this.file_mode.DATA_URI:
				if (typeof suggested_mime != "string")
					return D.readAsDataURL(fileUrl);
				else // apply mime override
					return D.readAsDataURL(fileUrl).replace(/^data:(\s*)([^;]*)/, "data:$1"+suggested_mime);
				break;
			case this.file_mode.BASE64:
				return D.readAsDataURL(fileUrl).replace(reDataUrlPfx, '');
			case this.file_mode.BINARY:
				return D.readAsBinaryString();
			case this.file_mode.UTF8_TEXT:
				return D.readAsText("utf-8");
			case this.file_mode.UTF16_TEXT:
				return D.readAsText("utf-16");
			case this.file_mode.ASCII_TEXT:
				return D.readAsText("");
		}
	} catch (e) {
		woas.log("ECMALoadFile: "+e);
		return false;
	}
	// not available
	this.crash(this.i18n.MODE_NOT_AVAIL.sprintf(load_mode.toString(16)));
	return null;
};*/

// API1.0: load-file handler
woas.load_file = function(fileUrl, load_mode, mime){
	// parameter consistency check
	if (!load_mode) {
		woas.log("WARNING: No load mode specified, defaulting to UTF8_TEXT");
		// perhaps should be ASCII?
		load_mode = this.file_mode.UTF8_TEXT;
	}
	// try loading the file without using the path (FF3+)
	// (object id hardcoded here)
	var r = null;
	if (!this.use_java_io) {
		// correctly retrieve fileUrl
		if (fileUrl === null) {
			if (this.browser.firefox3 || this.browser.firefox_new)
				r = this.mozillaLoadFileID("filename_", load_mode, mime);
			else
				fileUrl = this.get_input_file_url();
		}
		if (r === null) // load file using file absolute path
			r = this.mozillaLoadFile(fileUrl, load_mode, mime);
		else return r;
		if(r === false)
			return false;
		// attempt using ECMAscript
		// disabled because no browser support it yet
/*		if (r === null)
			r = this.ECMALoadFile(fileUrl, load_mode, mime);
		else return r; */
		// no mozillas here, attempt the IE way
		if (r === null)
			r = this.ieLoadFile(fileUrl, load_mode, mime);
		else return r;
		if (r === false)
			return false;
//		if (r === null)
			// finally attempt to use Java
//			r = this.javaLoadFile(fileUrl, load_mode);
	} else {
		if (fileUrl === null)
			fileUrl = this.get_input_file_url();
		if (fileUrl === false)
			return false;
		r = this.javaLoadFile(fileUrl, load_mode, mime);
	}
	if (r === false)
		return false;
	if (r === null) {
		this.alert('Could not load "'+fileUrl+'"');
		return null;
	}
	// wow, java worked!
	return r;
};

// the following load/save bindings will return:
// * null if they can't do it
// * false if there's an error
// * true if it saved OK
// * string with content if content was read successfully

// save through ActiveX
woas.ieSaveFile = function(filePath, save_mode, content) {
	var s_mode;
	switch (save_mode) {
		default:
/*		case this.file_mode.BINARY:
		case this.file_mode.DATA_URI:
		case this.file_mode.BASE64: */
			this.crash(this.i18n.MODE_NOT_AVAIL.sprintf(save_mode.toString(16)));
			return null;
		break;
		case this.file_mode.ASCII_TEXT:
			s_mode = 0; // ASCII
		break;
		case this.file_mode.UTF8_TEXT:
		case this.file_mode.UTF16_TEXT:
			s_mode = -1; // Unicode mode 
		break;
	}
	// first let's see if we can do ActiveX
	var fso;
	try	{
		fso = new ActiveXObject("Scripting.FileSystemObject");
	}
	catch (e) {
		return null;
	}
	try {
		var file = fso.OpenTextFile(filePath, 2, true, s_mode);
		file.Write(content);
		file.Close();
	}
	catch(e) {
		woas.log("ERROR: exception while attempting to save: " + e.toString());	// log:1
		return false;
	}
	return true;
};

// load through ActiveX
woas.ieLoadFile = function(filePath, load_mode, suggested_mime) {
	var o_mode;
	switch (load_mode) {
		//TODO: use Java applet for these modes
		//TODO: allow these modes when file is supposedly ASCII
/*		case this.file_mode.DATA_URI:
		case this.file_mode.BINARY:
		case this.file_mode.BASE64: */
		default:
			// not available
			this.crash(this.i18n.MODE_NOT_AVAIL.sprintf(load_mode.toString(16)));
			return null;
		case this.file_mode.ASCII_TEXT:
			o_mode = 0; // ASCII
		break;
		case this.file_mode.UTF16_TEXT:
		case this.file_mode.UTF8_TEXT:
			o_mode = -1; // Unicode
		break;
	}
	var fso, content = null;
	try	{
		fso = new ActiveXObject("Scripting.FileSystemObject");
	}
	catch (e) {
		woas.log(e);
		return null;
	}
	try {
		// attempt to open as unicode
		var file = fso.OpenTextFile(filePath,1,false,o_mode);
		content = file.ReadAll();
		file.Close();
	}
	catch(e) {
		woas.log("ERROR: exception while attempting to load\n\n" + e.toString());	// log:1
		return false;
	}
	// return a valid DATA:URI
/*	if (load_mode == this.file_mode.DATA_URI)
		return this._data_uri_enc(filePath, content, suggested_mime);
	else if (load_mode == this.file_mode.BASE64)
		return this.base64.encode(content); */
	return content;
};

// save through UniversalXPConnect
woas.mozillaSaveFile = function(filePath, save_mode, content) {
	if (!window.Components)
		return null;
	//FIXME: save_mode is not considered here
	try	{
		netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
		var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
		file.initWithPath(filePath);
		if (!file.exists())
			file.create(0, 0664);
		else
			woas.log("NOTICE: file \""+filePath+"\" exists, overwriting");	// log:1
		var out = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
		out.init(file, 0x08 | 0x20 | 0x02, 0700, 0);
		out.write(content, content.length);
		out.flush();
		out.close();
	}
	catch(e) {
		woas.log("NOTICE: exception while attempting to save:\n\n" + e);	// log:1
		return(false);
	}
	return(true);
};

// load through UniversalXPConnect
woas.mozillaLoadFile = function(filePath, load_mode, suggested_mime) {
	// this is available on Mozilla browsers only
	if (!window.Components)
		return null;
	try	{
		netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
		var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
		file.initWithPath(filePath);
		if (!file.exists()) {
			woas.log("NOTICE: unexisting file "+filePath);
			return false;
		}
		var inputStream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
		inputStream.init(file, 0x01, 04, 0);
		var sInputStream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
		sInputStream.init(inputStream);
		if ( (load_mode == this.file_mode.UTF8_TEXT) ||
			 (load_mode == this.file_mode.ASCII_TEXT))
			return sInputStream.read(sInputStream.available());
		// this byte-by-byte read allows retrieval of binary files
		var tot=sInputStream.available(), i=tot;
		var rd=[];
		while (i-->=0) {
			var c=sInputStream.read(1);
			rd.push(c.charCodeAt(0));
		}
		if (load_mode == this.file_mode.BINARY)
			return(this.merge_bytes(rd));
		else if (load_mode == this.file_mode.DATA_URI)
			return this._data_uri_enc_array(filePath, rd, suggested_mime);
		else if (load_mode == this.file_mode.BASE64)
			return this.base64.encode_array(rd);
	}
	catch(e) {
		woas.log("NOTICE: exception while attempting to load:\n\n" + e);	// log:1
	}
	return false;
};

//FIXME: save_mode is not enforced
woas.javaSaveFile = function(filePath,save_mode,content) {
	if ((save_mode != this.file_mode.ASCII_TEXT) && (save_mode != this.file_mode.UTF8_TEXT)) {
		woas.log("Only ASCII and UTF8 file modes are currently supported with Java/TiddlySaver");	//log:1
		return null;
	}
	var encoding = (save_mode === this.file_mode.ASCII_TEXT) ? "" : "UTF-8";
	try {
		if(document.applets.TiddlySaver) {
			var rv = document.applets.TiddlySaver.saveFile(filePath, encoding, content);
			if (typeof rv == "undefined") {
				woas.log("Save failure, this is usually a Java configuration issue");
				return null;
			} else {
				return rv ? true : false;
			}
		}
	} catch(ex) {
		// report but check next method
		woas.log("TiddlySaver applet not available"); //log:1
	}
	// check if no JRE is available
	if (typeof java == "undefined") {
		woas.log("No JRE detected"); //log:1
		return null;
	}
	// try reading the file with java.io
	try {
		var s = new java.io.PrintStream(new java.io.FileOutputStream(filePath));
		s.print(content);
		s.close();
	} catch(ex) {
		woas.log("Failed reading file directly with Java: "+ex.toString());
		return false;
	}
	return true;
};

//FIXME: UTF8_TEXT/BINARY is not enforced here
woas.javaLoadFile = function(filePath, load_mode, suggested_mime) {
	if ((load_mode != this.file_mode.ASCII_TEXT) && (load_mode != this.file_mode.UTF8_TEXT)) {
		woas.log("Only ASCII and UTF8 file modes are currently supported with Java/TiddlySaver");	//log:1
		return null;
	}
	var encoding = (load_mode === this.file_mode.ASCII_TEXT) ? "" : "UTF-8",
		content = null;
	try {
		if(document.applets.TiddlySaver) {
			content = document.applets.TiddlySaver.loadFile(filePath, encoding);
			if (content === null) {
				woas.log("Load failure, maybe file does not exist? "+filePath); //log:1
				return false;
			}
			// check that it is not an "undefined" string
			if (typeof content == "undefined") {
				woas.log("Load failure, this is usually a Java configuration issue"); //log:1
				return null;
			}
			// convert to string only after checking that it was successfully loaded
			content = String(content);
			if (load_mode == this.file_mode.DATA_URI)
				return this._data_uri_enc(filePath, content, suggested_mime);
			else if (load_mode == this.file_mode.BASE6)
				return this.base64.encode(content);
			return content;
		}
	} catch(ex) {
		// report but check next method
		woas.log("TiddlySaver applet not available"); //log:1
	}
	// check if no JRE is available
	if (typeof java == "undefined") {
		woas.log("No JRE detected"); //log:1
		return null;
	}
	content = "";
	var r, line;
	try {
		r = new java.io.BufferedReader(new java.io.FileReader(filePath));
		while((line = r.readLine()) !== null)
			content += new String(line) + "\n";
		r.close();
	} catch(ex) {
		woas.log("Exception in javaLoadFile(\""+filePath+"\"): "+ex);
		return false;
	}
	if (load_mode == this.file_mode.DATA_URI)
		return this._data_uri_enc(filePath, content, suggested_mime);
	else if (load_mode == this.file_mode.BASE64)
		return this.base64.encode(content);
	return content;
};

function printout_arr(arr, split_lines) {

	function elem_print(e) {
		return "'" + woas.js_encode(e, split_lines) + "'";
	}

	var s = "";
	for(var i=0;i < arr.length-1;i++) {
		s += elem_print(arr[i]) + ",\n";
	}
	if (arr.length>1)
		s += elem_print(arr[arr.length-1]) + "\n";
	return s;
}

function printout_mixed_arr(arr, split_lines, attrs) {

	function elem_print(e, attr) {
		if (attr & 2) {
			return "[" + printout_num_arr(e) + "]";
		}
		return "'" + woas.js_encode(e, split_lines) + "'";
	}

	var s = "";
	for(var i=0;i < arr.length-1;i++) {
		s += elem_print(arr[i], attrs[i]) + ",\n";
	}
	if (arr.length>1)
		s += elem_print(arr[arr.length-1], attrs[arr.length-1]) + "\n";
	return s;
}

// used to print out encrypted page bytes and attributes
function printout_num_arr(arr) {
	var s = "",it=arr.length-1;
	for(var i=0;i<it;i++) {
		if (arr[i]>=1000)
			s += "0x"+arr[i].toString(16) + ",";
		else
			s+=arr[i].toString() + ",";
	}
	// do not write comma on last element, workaround due to IE6 not recognizing it
	if (it>0) {
		if (arr[it]>=1000)
			s += "0x"+arr[it].toString(16);
		else
			s+=arr[it].toString();
	}

	return s;
}

function printout_fixed(elem, n) {
	var s = (elem+",").repeat(n-1);
	// do not write comma on last element, workaround due to IE6 not recognizing it
	if (n>1)
		s += elem;
	return s;
}

// save full WoaS to file
woas._save_to_file = function(full) {
	this.progress_init("Saving to file");

	// force full mode if WSIF datasource mode changed since last time loading/saving
	var ds_changed = (this.config.wsif_ds.length !== this._old_wsif_ds_len),
	// increase the marker only when performing full save
		new_marker = ((full | ds_changed) && !this.config.wsif_ds.length) ? this._inc_marker(__marker) : __marker,
		safe_current;

	// setup the page to be opened on next start
	if (this.config.nav_history) {
		if (!this.page_exists(current))
			safe_current = this.config.main_page;
		else safe_current = current;
	} else
		safe_current = this.config.main_page;
	
	// output the javascript header and configuration flags
	var computed_js = "\n/* <![CDATA[ */\n\n/* "+new_marker+"-START */\n\nvar woas = {\"version\": \""+this.version+
	"\"};\n\nvar __marker = \""+new_marker+"\";\n\nwoas[\"config\"] = {";
	for (var param in this.config) {
		computed_js += "\n\""+param+"\":";
		switch(typeof(this.config[param])) {
			case "boolean":
				computed_js += (this.config[param] ? "true" : "false")+",";
			break;
			case "string":
				computed_js += "'"+this.js_encode(this.config[param])+"',";
			break;
			default: // for numbers
				computed_js += this.config[param]+",";
			break;
		}
	}
	computed_js = computed_js.substr(0,computed_js.length-1);
	computed_js += "};\n";
	
	computed_js += "\nvar current = '" + this.js_encode(safe_current)+"';\n\n";
	
	computed_js += "var backstack = [\n" + printout_arr(this.config.nav_history ? backstack : [], false) + "];\n\n";
	
	// in WSIF datasource mode we will save empty arrays
	if (this.config.wsif_ds.length !== 0)
		computed_js += "var page_titles = [\n];\n\n";
	else
		computed_js += "var page_titles = [\n" + printout_arr(page_titles, false) + "];\n\n";
	
	computed_js += "/* " + new_marker + "-DATA */\n";

	if (full || ds_changed) {
		this._old_wsif_ds_len = this.config.wsif_ds.length;
		if (this.config.wsif_ds.length) {
			// everything empty when the javascript layer is not used
			computed_js += "var page_attrs = [];\n\n";
			computed_js += "var page_mts = [];\n\n";
			computed_js += "var pages = [\n];\n\n";
		} else {
			computed_js += "var page_attrs = [" + printout_num_arr(page_attrs) + "];\n\n";
			computed_js += "var page_mts = [" + (this.config.store_mts ? printout_num_arr(page_mts) : "0, ".repeat(page_mts.length-1)+"0") + "];\n\n";
			computed_js += "var pages = [\n" + printout_mixed_arr(pages, this.config.allow_diff, page_attrs) + "];\n\n";
		}
		computed_js += "/* " + new_marker + "-END */\n";
	}

	// cleanup the DOM before saving
	var bak_ed = d$("woas_editor").value,
		bak_tx = this.getHTMLDiv(d$("woas_wiki_area")),
		bak_mn = this.getHTMLDiv(d$("woas_menu_area")),
		bak_mts = this.getHTMLDiv(d$("woas_mts")),
		bak_mts_shown = d$.is_visible("woas_mts"),
		bak_wait_text = this.getHTML(d$("woas_wait_text")),
		bak_debug = d$("woas_debug_log").value,
	// clear titles and css as well as they will be set on load.
		bak_title = this.getHTMLDiv(d$("woas_title"));

	if (bak_mts_shown)
		d$.hide("woas_mts");
	d$("woas_editor").value = "";
	this.setHTMLDiv(d$("woas_wiki_area"), "");
	this.setHTMLDiv(d$("woas_menu_area"), "");
	this.setHTMLDiv(d$("woas_mts"), "");
	this.setHTMLDiv(d$("woas_title"), "");
	d$("woas_debug_log").value = "";

	// set the loading message
	this.setHTML(d$("woas_wait_text"), this.i18n.LOADING);
	// temporarily display such message
	d$.show("loading_overlay");
	var bak_cursor = document.body.style.cursor;
	document.body.style.cursor = "auto";

	var data = this._extract_src_data(__marker, document.documentElement.innerHTML, full | ds_changed, safe_current);
	
	// data is ready, now the actual save process begins
	var r=false;
	d$.hide("loading_overlay");
	this.setHTML(d$("woas_wait_text"), bak_wait_text);
	document.body.style.cursor = bak_cursor;

	//DEBUG check
	if (data.length === 0) {
		this.crash("Could not retrieve original DOM data!");
	} else {
	
//	if (!this.config.server_mode || (was_local && this.config.server_mode)) {
	if (!this._server_mode)
		r = this._save_this_file(computed_js, data);
//		was_local = false;
//	}

	// save was successful - trigger some events
	if (r) {
		this.after_config_saved();
		if (full)
			this.after_pages_saved();
	}
	} //DEBUG check

	d$("woas_editor").value = bak_ed;
	this.setHTMLDiv(d$("woas_wiki_area"), bak_tx);
	this.setHTMLDiv(d$("woas_menu_area"), bak_mn);
	this.setHTMLDiv(d$("woas_mts"), bak_mts);
	if (bak_mts_shown)
		d$.show("woas_mts");
	d$("woas_debug_log").value = bak_debug;
	this.setHTMLDiv(d$("woas_title"), bak_title);
	
	//TODO: re-run after parsing hooks
	// would fix issues with import page for example
	
	this.progress_finish();
	
	return r;
};

function reXHTMLFix_hook(str, tag) {
	var l=str.length;
	if (str.charAt(l-1)!=='/')
		str = str.substr(0, l-1)+" />";
	return str;
}
var reXHTMLFix = /<(img|hr|br|input|meta)[^>]*>/gi;

var reHeadTagEnd = new RegExp("<\\/"+"head[^>]*>", "ig");
	reHeadTagStart = new RegExp("<"+"head[^>]*>", "ig"),
	reTagStart = /<(\w+)([^>]*)>/g,
	reTagEnd = /<\/(\w+)[^>]*>/g,
	reEditorTA = new RegExp('<'+'textarea\\s+id="?woas_editor"?\\s*[^>]+>(.*?)<'+'/textarea>', 'gi'),
	reCKDiv = new RegExp('<'+'div\\s+id="?woas_custom_accesskeys"?\\s*>(.*?)<'+'/div>', 'gi');

woas._extract_src_data = function(marker, source, full, current_page, data_only) {
	var e_offset, s_offset;
	// find the start marker for safety checking
	s_offset = source.indexOf("/* "+marker+ "-START */");
	if (s_offset === -1) {
		this.alert(this.i18n.ERR_MARKER.sprintf("START"));
		return false;
	}			
	// find the end marker, necessary to make some DOM/XHTML fixes
	e_offset = source.indexOf("/* "+marker+ "-END */", s_offset);
	if (e_offset === -1) {
		this.alert(this.i18n.ERR_MARKER.sprintf("END"));
		return false;
	}
	// properly update offset (+2 is for newlines)
	e_offset += 3 + marker.length + 7 + 2;
	
	// used during import
	if (full && data_only) {
		return source.substring(s_offset, e_offset);
	}

	reHeadTagStart.lastIndex = 0;
	var head_start, head_end,
		m = reHeadTagStart.exec(source);
	if (m !== null)
		head_start = m.index+m[0].length;
	else {
		this.crash("Cannot find head start tag");
		return false;
	}
	// search for head end tag starting at data end offset
	reHeadTagEnd.lastIndex = e_offset;
	m = reHeadTagEnd.exec(source);
	if (m !== null)
		head_end = m.index + m[0].length;
	else {
		this.crash("Cannot find head end tag");
		return false;
	}
	
	// filter out the unimportant tags from head
	// build a list of replacements with offsets
	
	// first take away the head
	var needle, m2, l_attrs, the_head = source.substring(0, head_end),
		splicings = [], tag_end,
		rest_of_source = source.substring(head_end);
	// reset big string
	source = "";
	// skip non-head content
	reTagStart.lastIndex = head_start;
	
	m = reTagStart.exec(the_head);
	while (m !== null) {
		tag = m[1].toLowerCase();
		var broken=false;
		switch (tag) {
			case "script":
			case "style":
			case "title":
				reTagEnd.lastIndex = m.index + m[0].length;
				do {
					m2 = reTagEnd.exec(the_head);
					if (m2 === null) {
						woas.log("found "+m[1]+" without closing tag");
						// continue to check for permanent attribute
						broken = true;
						break;
					}
					close_tag = m2[1].toLowerCase();
				} while (close_tag !== tag);
				// fallback wanted to set tag end like if it was a single tag
				if (!broken) {
					tag_end = tag_end = m2.index+m2[0].length;
					break;
				}
			case "meta":
				tag_end = m.index+m[0].length;
				break;
			default:
//				woas.log("Unknown tag in head: "+tag);
				// continue to check for permanent attribute
				tag_end = m.index+m[0].length;
				broken = true;
			break;
		}
		
		l_attrs = m[2].toLowerCase();
		// this was marked as permanent tag
		var was_replaced = false;
		if (l_attrs.indexOf("woas_permanent=")!==-1) {
			if (!broken) {
			if (tag === "style") {
				was_replaced = true;
				if (l_attrs.indexOf("woas_core_style=")!==-1) {
					woas.log("Replacing CSS");
					needle = m[0]+woas.get_text("WoaS::CSS::Boot")+m2[0];
				} // else leave as-is
			} else if (tag === "title") {
				woas.log("Replacing title");
				needle = m[0]+woas.xhtml_encode(current_page)+m2[0];
				was_replaced = true;
			}
			}
			// will leave tag untouched
		} else {
			woas.log("Removing tag "+tag);
			needle = "";
			was_replaced = true;
		}
		if (was_replaced)
			// add this splicing
			splicings.push( { start: m.index, end: tag_end, needle: needle } );
		reTagStart.lastIndex = tag_end;
		m = reTagStart.exec(the_head);
	}

	// rebuild the source by using splicings
	if (splicings.length) {
		var prev_ofs = 0;
		for(var i=0;i < splicings.length;++i) {
			source += the_head.substring(prev_ofs, splicings[i].start) + splicings[i].needle;
			prev_ofs = splicings[i].end;
		} splicings = null;

		// XHTML hotfixes (FF doesn't either save correctly)
		source += the_head.substr(prev_ofs); the_head = null;
		
		// re-calculate offsets
		
		// find the start marker for safety checking
		s_offset = source.indexOf("/* "+marker+ "-START */");
		if (s_offset === -1) {
			this.alert(this.i18n.ERR_MARKER.sprintf("START"));
			return false;
		}			
		// find the end marker, necessary to make some DOM/XHTML fixes
		e_offset = source.indexOf("/* "+marker+ "-END */", s_offset);
		if (e_offset === -1) {
			this.alert(this.i18n.ERR_MARKER.sprintf("END"));
			return false;
		}
		// properly update offset (+2 is for newlines)
		e_offset += 3 + marker.length + 7 + 2;
	} else {
		source = the_head;
		the_head = null;
	}
	
	// remove the tail (if any)
	var tail_end_mark = "<"+"!-- "+marker+"-TAIL-END -"+"->",
		tail_st_mark = "<"+"!-- "+marker+"-TAIL-START --"+">",
		tail_start = rest_of_source.indexOf(tail_st_mark, e_offset);
	if (tail_start !== -1) {
		var tail_end = rest_of_source.indexOf(tail_end_mark, tail_start);
		if (tail_end === -1)
			woas.log("Cannot find tail end!"); //log:1
		else {
			// remove the tail content (but not the tail itself)
			rest_of_source =	rest_of_source.substring(0, tail_start + tail_st_mark.length)+
						rest_of_source.substring(tail_end+tail_end_mark.length);
		}
	}

	// replace textarea with a standard one
	source += rest_of_source.replace(reEditorTA, '<'+'textarea id="woas_editor" rows="0" cols="0">&'+'nbsp;<'+'/textarea>')
	// remove the custom keys defined
			.replace(reCKDiv, '<'+'div id="woas_custom_accesskeys">&'+'nbsp;<'+'/div>')
	// XHTML hotfixes (FF2/FF3 doesn't either save correctly)
			.replace(reXHTMLFix, reXHTMLFix_hook);
	rest_of_source = null;
	
	if (!full) {
		e_offset = source.indexOf("/* "+marker+ "-DATA */", s_offset);
		if (e_offset === -1) {
			this.alert(this.i18n.ERR_MARKER.sprintf("DATA"));
			return false;
		}
		e_offset += 3 + marker.length + 8 + 1 /* newlines */;
	}
	return source.substring(e_offset);
};

// increment the save-counter portion of the marker
var reMarker = /([^\-]*)\-(\d{7,7})$/;
woas._inc_marker = function(old_marker) {
	var m = old_marker.match(reMarker);
	if (m===null)
		return _random_string(10)+"-0000001";
	var n = new Number(m[2].replace(/^0+/, '')) + 1;
	n = n.toString();
	// marker part + 0-padded save count number
	return m[1]+"-"+String("0").repeat(7-n.length)+n;
};

// load URL via XHR
woas.remote_load = function(url) {
	var HttpReq = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
	HttpReq.open('GET', url, false);
	HttpReq.setRequestHeader('Content-Type', 'text/plain');
	HttpReq.send(null);
	return HttpReq.responseText;
};

/*** src/parser.js ***/
// module @parser
woas.parser = {
	render_title: null,			// title of page being rendered
	has_toc: null,
	toc: "",
	force_inline: false,		// used not to break layout when presenting search results
	inline_tags: 0,
	_parsing_menu: false,		// true when we are parsing the menu page
	// properties used by _transclude
	_snippets: null,
	_export_links: null,

	header_anchor: function(s) {
		// apply a hard normalization
		// WARNING: will not preserve header ids uniqueness
		return s.replace(this.reNormHeader, '_')
	},
	
	// @override to apply some further customization before parse output
	after_parse: function(P) {
	},
	
	// @override to parse further syntax before final replace
	extend_syntax: function(P) {
	},

	render_error: function(str, symbol) {
		//	if (typeof symbol == "undefined")
		//		symbol = "infin";
		symbol = "&"+symbol+";";
		return "<"+"span style=\"color:red;font-weight:bold;\">"+symbol+" "+str+" "+symbol+"<"+"/span>";
	},
	
	// a variety of regular expressions used by the parser
	reBoldSyntax: /([^\w\/\\])\*([^\*\n]+)\*/g,
	//DEPRECATED "!" syntax is supported but shall me removed soon
	reHeaders: /^([\!=]{1,6})\s*(.*)$/gm,
	reNormHeader: /[^a-zA-Z0-9]/g,
	sTOC: "[[Special::TOC]]",
	reHasDNL: new RegExp("^([ \\t]*\\n)"),
	_MAX_TRANSCLUSION_RECURSE: 256,

	marker: null,
	reBaseSnippet: null,
	_HR: "<"+"hr class=\"woas_ruler\" />",
	NL_MARKER: null,
	reNL_MARKER: null,
	_init: function() {
		this.marker = "#"+_random_string(8);
		this.reBaseSnippet = new RegExp("<\\!-- "+this.marker+"::(\\d+) -->", "g");
		this.NL_MARKER = "<!-- "+this.marker+"_NL -->";
		this.reNL_MARKER = new RegExp("<\\!-- "+this.marker+"_NL -->([ \\t]*\\n)?", "g");
	}
};

// initialize here because IE would fail otherwise
woas.parser._init();

woas.parser.header_replace = function(str, $1, $2) {
		var header = $2, len = $1.length,
		// remove the mirrored header syntax from right
			hpos = header.lastIndexOf($1),
			that = woas.parser;
		if ((hpos !== -1) && (hpos === header.length - len))
			header = header.substring(0, header.length - len);
		// automatically build the TOC if needed
		if (that.has_toc) {
			that.toc += String("#").repeat(len)+" <"+"a class=\"woas_link\" href=\"#" +
			that.header_anchor(header) + "\">" + header + "<\/a>\n";
		}
		return "<"+"h"+len+" class=\"woas_header\" id=\""+that.header_anchor(header)+"\">"+header+"<"+"/h"+len+">";
};

woas.parser.sublist = function (lst, ll, suoro, euoro) {   
	if (!lst.length)
		return '';
	
	if (lst[0][1].length > ll)
		return this.sublist(lst, ll+1, suoro, euoro);
	
	var item, subl, s = '';
	while (lst[0][1].length == ll ) {
                item = lst.shift();
                subl = this.sublist(lst, ll + 1, suoro, euoro);
                if (subl.length)
                    s += '<'+'li>' + item[2] + suoro + subl + euoro + '<'+'/li>' ;
                else
                    s += '<'+'li>' + item[2] + '<'+'/li>';
		if (!lst.length)
			break;
	}
	return s;  
};

// XHTML lists and tables parsing code by plumloco
// There is no limit to the level of nesting and produces valid XHTML markup
var reReapLists = /^([\*#@])[ \t].*(?:\n\1+[ \t].+)*/gm,
	reItems = /^([\*#@]+)[ \t]([^\n]+)/mg;
woas.parser.parse_lists = function(str, type, $2) {
	var uoro = (type!='*')?'ol':'ul',
		suoro = '<' + uoro + ((type=='@') ? " type=\"a\"":"")+'>',
		euoro = '</' + uoro + '>',
		// collect all items in a stack
		stk = [];

	str.replace( reItems, function(str, p1, p2) {
		stk.push([str, p1, p2]);
	} );

	return suoro + woas.parser.sublist(stk, 1, suoro, euoro) + euoro;
};

// new table parsing by FBNil
var reReapTablesNew = /^\{\|(.*)((?:\n\|.*)*)$/gm,
	reReapTablesNewSub1 = /\n\|([+ \t-\|])(.*)/g,
	reReapTablesNewSub2 = /(\|\|)(\s{0,1})(\s?)(?=\|\|)/g,
	reReapTablesNewSub3 = /(\|\|\s*)$/,
	reReapTablesNewSub4 = /\|\|\t/g,
	reReapTablesNewSub5 = /\t\|\|/g,
	reReapTablesHead = /^(\s*)(?:(=+)\s*)?(.*?)(\s*)$/;
woas.parser.parse_tables_new = function (str, prop, p1) {
    var caption = '',
		colgroup = '',
		stk = [],
		cols = [],
		CC = [];
	// variables used by replace callback
	var i, C, CL;
    p1.replace(reReapTablesNewSub1, function (str, pp1, pp2) {
		switch (pp1) {
			case '-': // comment
				return;
			case '+':
				return caption = caption || ('<'+'caption' + (stk.length > 0 ? ' style="caption-side:bottom">' : '>') + pp2 + '<'+'/caption>');
			case '*':
				return colgroup = pp2;
			case '$':
				return CC.push(pp2);
			case '|':
				pp2 = " |" + pp2;
			break;
			case ' ':
				if (pp2.match(/^\|/)) // fix empty first cell
					pp2 = "  " + pp2;
			break;
			default:
				// do not eat the first character if it's not a control character
				pp2 = pp1+pp2;
		}

        var cells = pp2.replace(reReapTablesNewSub2, "$1$2$3  ").
				replace(reReapTablesNewSub3, "$1 ").
				replace(reReapTablesNewSub4, "|| ").
				replace(reReapTablesNewSub5, " ||").split(" || "),
			row = [],
			stag = "",
			cs = 0;
        for (i = cells.length - 1; i >= 0; --i) {
            C = cells[i].match(reReapTablesHead);
            if (i && !C[3] && !C[1] && !C[2]) {
                ++cs;
                continue;
            } else if (i == 0 && !C[3]) C[3] = "&nbsp;";
            CL = C[2] ? C[2].length : 0;
            stag = '<' + (CL == 1 ? 'th' : 'td') + (CL > 1 ? ' ' + CC[CL - 2] || '' : '') + (cs ? ' colspan=' + (++cs) : '') + (C[1] ? ' align=' + (C[4] ? 'center' : 'right') : '') + '>';
            cs = 0;
            row.unshift(stag + C[3] + (CL == 1 ? '<'+'/th>' : '<'+'/td>'));
        }
        stk.push(row.join(""));
    });
    return '<'+'table ' + ((prop.indexOf("class=")!==-1) ? '' : 'class="woas_text_area" ') + prop + '>' + caption + colgroup + '<'+'tr>' + stk.join('<'+'/tr><'+'tr>') + '<'+'/tr>' + '<'+'/table>'
};

// extract the wiki tags from a wiki URL
woas._get_tags = function(text, last_tag) {
	var tags = [];
	// remove the starting part
	if (text.substr(0, 5) === "Tag::")
		text = this.trim(text.substring(5));
	else if (text.substr(0,6)==="Tags::") {
		woas.log("Using deprecated 'Tags' namespace");
		text = this.trim(text.substring(6));
	} else // not a valid tagging
		return tags;
	// check length only after having removed the part we don't need
	if (!text.length)
		return tags;
	var alltags = this.split_tags(text), tag;
	if (last_tag !== null) alltags = alltags.concat(this.split_tags(last_tag));
	for(var i=0;i < alltags.length;i++) {
		tag = this.trim(alltags[i]);
		if (tags.indexOf(tag)===-1)
			tags.push(tag);
	}
	return tags;
};

// split one or more tags
//NOTE: no trim applied
woas.split_tags = function(tlist) {
	if (tlist.indexOf(",")!==-1)
		return tlist.split(",");
	//DEPRECATED but still supported
	return tlist.split("|");
};

// elements which can have one dynamic newline
var reScripts = new RegExp("<"+"script([^>]*)>([\\s\\S]*?)<"+"\\/script>([ \t]*\n)?", "gi"),
	reStyles = new RegExp("<"+"style([^>]*)>[\\s\\S]*?<"+"\\/style>([ \t]*\n)?", "gi"),
	//DEPRECATED rulers with 3 hyphens (shall be 4)
	reRuler = /(\n\s*\-{3,}[ \t]*){1,}(\n|$)/g,
	reNowikiSL = /\n\{\{\{([\s\S]*?)\}\}\}[ \t]*\n/g,
	reNowiki = /\{\{\{([\s\S]*?)\}\}\}([ \t]*\n)?/g,
	reTransclusion = /\[\[Include::([\s\S]+?)\]\]([ \t]*\n)?/g,
	reMacros = /<<<([\s\S]*?)>>>([ \t]*\n)?/g,
	reComments = /<\!--([\s\S]*?)-->([ \t]*\n)?/g,
// the others have not
	reWikiLink = /\[\[([^\]\]]*?)\|(.*?)\]\]/g,
	reWikiLinkSimple = /\[\[([^\]]*?)\]\]/g,
	reMailto = /^mailto:\/\//,
	reCleanupNewlines = new RegExp('((<\\/h[1-6]>)|(<\\/[uo]l>))(\n+)', 'g');

woas.parser.place_holder = function (i, separator, dynamic_nl) {
	if (typeof separator == "undefined")
		separator = "";
	if (typeof dynamic_nl == "undefined")
		dynamic_nl = "";
	else if (dynamic_nl !== "") // put newlines after blocks which have an ending newline
		dynamic_nl = this.NL_MARKER+dynamic_nl;
	separator = ":"+separator+":";
	return "<!-- "+woas.parser.marker+separator+i+" -->"+dynamic_nl;
};

// create a preformatted block ready to be displayed
woas._make_preformatted = function(text, add_style) {
	var cls = "woas_nowiki", tag, p = text.indexOf("\n");
	if (p === -1) {
		tag = "tt";
	} else {
		// remove the first newline to be compliant with old parsing
		if (p===0)
			text = text.substr(1);
		cls += " woas_nowiki_multiline";
		tag = "pre";
	}
	return this._raw_preformatted(tag, text, cls, add_style);
};

woas._raw_preformatted = function(tag, text, cls, add_style) {
	var xhtml = this.xhtml_encode(text);
	// convert the newlines - not necessary with pre tags
//	if (this.browser.ie)		xhtml = xhtml.replace(/\n/g, "\r\n");
	// to ease copy/pasting
//	xhtml = xhtml.replace(/\n/g, "<"+"br />");
	if (typeof add_style != "undefined")
		add_style = " style=\""+add_style+"\"";
	else add_style = "";
	return "<"+tag+" class=\""+cls+"\""+add_style+">"+xhtml+"</"+tag+">";
};

// This method can be overriden to customize parsing
// Other useful callbacks to control flow of page display: woas.after_parse and woas.pager.browse

// 'text' is the raw wiki source
// 'export_links' is set to true when exporting wiki pages and is used to generate proper href for hyperlinks
// 'js_mode' controls javascript behavior. Allowed values are:
// 0 = leave script tags as they are (used for exporting)
// 1 - place script tags in head (dynamic),
// 2 - re-add script tags after parsing
// 3 - convert script tags to nowiki blocks
woas.parser.parse = function(text, export_links, js_mode) {
	if (woas.config.debug_mode) {
		if ((typeof text).toLowerCase() != "string") {
			woas.crash("Called parse() with invalid argument: "+(typeof text));	// log:1
			return null;
		}
	}
	// default fallback
	if (typeof export_links == "undefined")
		export_links = false;
	if (typeof js_mode == "undefined")
		js_mode = 1;
	
	// put text in an object
	var P = { body: text }; text = null;
	// snippets array will contain all the HTML snippets that will not be parsed by the wiki engine
	var snippets = [], r, backup_hook = this.after_parse;
	
	// comments and nowiki blocks
	this.pre_parse(P, snippets);

	// macros
	this.parse_macros(P, snippets);
	
	// transclude pages (templates)
	if (!this.force_inline) {
		// reset all groups
		this._ns_groups = { };
		// apply transclusion syntax
		this.transclude_syntax(P, snippets, export_links);
	}
	
	if (js_mode) {
		// reset the array of custom scripts for the correct target
		var script_target = this._parsing_menu ? "menu" : "page";
		woas.scripting.clear(script_target);
		// gather all script tags
		P.body = P.body.replace(reScripts, function (str, $1, $2, dynamic_nl) {
			if (js_mode==2) {
				r = woas.parser.place_holder(snippets.length, "", dynamic_nl);
				snippets.push(str);
				return r;
			} else if (js_mode==3) {
				// during safe mode do not activate scripts, transform them to nowiki blocks
				r = woas.parser.place_holder(snippets.length, "", dynamic_nl);
				snippets.push( woas._make_preformatted(str) );
				return r;
			} // else
			var m=$1.match(/src=(?:"|')([^\s'">]+)/),
				external = (m!==null);
			woas.scripting.add(script_target, external ? m[1] : $2, external);
			return "";
		});
	}
	
	// take away style blocks
	P.body = P.body.replace(reStyles, function(str, $1, dynamic_nl) {
		r = woas.parser.place_holder(snippets.length, "", dynamic_nl);
		snippets.push(str);
		return r;
	});
	
	// put a placeholder for the TOC
	var p = P.body.indexOf(this.sTOC);
	if (p !== -1) {
		this.has_toc = true;
		P.body = P.body.substring(0, p) + "<!-- "+woas.parser.marker+":TOC -->" +
				// dynamic newlines also after TOC
				P.body.substring(p+this.sTOC.length).replace(this.reHasDNL, this.NL_MARKER+"$1");
	} else this.has_toc = false;

	// wiki tags
	var tags = [];
	this.inline_tags = 0;
	
	this.syntax_parse(P, snippets, tags, export_links, this.has_toc);

	// sort tags at bottom of page, also when showing namespaces
	tags = tags.toUnique().sort();
	if (tags.length && !export_links) {
		var s;
		if (this.force_inline)
			s = "";
		else
			s = "<"+"div class=\"woas_taglinks\">";
		s += "Tags: ";
		for(var i=0;i < tags.length;++i) {
			s += "<"+"a class=\"woas_link\" onclick=\"woas.go_to('Tagged::"+woas.js_encode(tags[i])+"')\">"+
				woas.xhtml_encode(tags[i])+"<"+"/a>&nbsp;&nbsp;";
		}
		if (!this.force_inline) {
			s+="<"+"/div>";
			P.body += s;
		} else { // re-print the inline tags (works only on last tag definition?)
			P.body = P.body.replace(new RegExp("<\\!-- "+woas.parser.marker+":(\\d+) -->", "g"), function (str, $1) {
				// loose comparison is OK here
				if ($1 == woas.parser.inline_tags)
					return s;
				return "";
			});
		}
	}
	// reset the flaggers
	if (this.force_inline)
		this.force_inline = false;
	if (woas.macro.has_backup())
		// restore macros array
		woas.macro.pop_backup();

	// syntax parsing has finished, do you want to apply some final cosmethic?
	if (this.after_parse === backup_hook)
		this.after_parse(P);
	
	// finished
	return P.body;
};

woas.parser.parse_macros = function(P, snippets) {
	// put away stuff contained in user-defined macro multi-line blocks
	P.body = P.body.replace(reMacros, function (str, $1, dynamic_nl) {
		if (!woas.macro.has_backup())
			// take a backup copy of the macros, so that no new macros are defined after page processing
			woas.macro.push_backup();

		// ask macro_parser to prepare this block
		var macro = woas.macro.parser($1);
		// allow further parser processing
		if (macro.reprocess) {
			if (typeof dynamic_nl != "undefined" && dynamic_nl!=="")
				macro.text += woas.parser.NL_MARKER+dynamic_nl;
			return macro.text;
		}
		r = woas.parser.place_holder(snippets.length, "", dynamic_nl);
		// otherwise store it for later
		snippets.push(macro.text);
		return r;
	});
};

//NOTE: XHTML comments cannot be contained in nowiki or macro blocks
woas.parser.pre_parse = function(P, snippets) {
	// put away XHTML-style comments
	P.body = P.body.replace(reComments, function (str, comment, dynamic_nl) {
		// skip whitespace comments
		if (comment.match(/^\s+$/))
			return str;
		r = woas.parser.place_holder(snippets.length, "", dynamic_nl);
		snippets.push(str);
		return r;
	})
	// put away stuff contained in inline nowiki blocks {{{ }}}
	.replace(reNowikiSL, function (str, $1) {
		r = woas.parser.place_holder(snippets.length, "", "\n");
		snippets.push("\n"+woas._raw_preformatted("pre", $1, "woas_nowiki woas_nowikimultiline"));
		return r;
	})
	.replace(reNowiki, function (str, $1, dynamic_nl) {
		r = woas.parser.place_holder(snippets.length, "", dynamic_nl);
		snippets.push(woas._make_preformatted($1));
		return r;
	});

};

//API1.0
//TODO: offer transclusion parameters argument
woas.parser.transclude = function(title, snippets, export_links) {
	this._snippets = snippets;
	this._export_links = export_links ? true : false;
	var rv = this._transclude("[[Include::"+title+"]]", title);
	this._export_links = this._snippets = null;
	return rv;
};

woas.parser._snippets = null;
woas.parser._transcluding = 0;
woas.parser._transclude = function (str, $1, dynamic_nl) {
	var that = woas.parser,
		parts = $1.split("|"),
		templname = parts[0],
		is_emb = false, ns=woas.get_namespace(templname, true),
		// temporary page object
		P = { body: null };
	// increase transclusion depth
	++that._transcluding;
//	woas.log("Transcluding "+templname+"("+parts.slice(0).toString()+")");	// log:0
	// in case of embedded file, add the inline file or add the image
	if (woas.is_reserved(templname) || (templname.substring(templname.length-2)=="::"))
		P.body = woas.get_text_special(templname);
	else {
		var epi = woas.page_index(templname);
		// offer a link for uploading, to implement feature as before 0.11.0
		if (epi == -1)
			P.body = "[<!-- -->[Include::[["+templname+"]]]]";
		else {
			P.body = woas.get__text(epi);
			is_emb = woas.is_embedded(templname);
		}
	}
	// template retrieval error
	if (P.body === null) {
		var templs="[["+templname+"]]";
		if (parts.length>1)
			templs += "|"+parts.slice(1).join("|");
		r = woas.parser.place_holder(that._snippets.length, "", dynamic_nl);
		// show an error with empty set symbol
		that._snippets.push(woas.parser.render_error(str, "#8709"));
		--that._transcluding;
		return r;
	}
	if (is_emb) {
		r = woas.parser.place_holder(that._snippets.length, "", dynamic_nl);
//		woas.log("Embedded file transclusion: "+templname);	// log:0
		if (woas.is_image(templname)) {
			var img, img_name = woas.xhtml_encode(templname.substr(templname.indexOf("::")+2));
			if (woas.parser._export_links) {
				// check that the URI is valid
				var uri=woas.exporter._get_fname(templname);
				if (uri == '#')
					img = woas.parser.render_error(templname, "#8709");
				else
					img = "<"+"img class=\"woas_embedded\" src=\""+uri+"\" alt=\""+img_name+"\" ";
			} else
				img = "<"+"img class=\"woas_embedded\" src=\""+P.body+"\" ";
			if (parts.length>1) {
				img += parts[1];
				// always add the alt attribute to images
				if (!woas.parser._export_links && !parts[1].match(/alt=('|").*?\1/))
					img += " alt=\""+img_name+"\"";
			}
			that._snippets.push(img+" />");
		} else { // embedded file but not image
			if ((parts.length>1) && (parts[1]=="raw"))
				that._snippets.push(woas.base64.decode(P.body));
			else
				that._snippets.push("<"+"pre class=\"woas_embedded\">"+
						woas.xhtml_encode(woas.base64.decode(P.body))+"<"+"/pre>");
		}
		P.body = r;
	}
	
	if (!is_emb) {
		// take away XHTML comments and nowiki blocks
		that.pre_parse(P, that._snippets);
		
		that.parse_macros(P, that._snippets);
		
		// finally replace transclusion parameters
		if (parts.length) {
			P.body = P.body.replace(/%\d+/g, function(str) {
				var paramno = parseInt(str.substr(1));
				if (paramno < parts.length)
					return parts[paramno];
				else
					return str;
			} );
		}
	} // not embedded
	--that._transcluding;
	//add the previous dynamic newline
	if (typeof dynamic_nl != "undefined" && dynamic_nl!=="")
		P.body += that.NL_MARKER+dynamic_nl;
	return P.body;
};

woas.parser.transclude_syntax = function(P, snippets, export_links) {
	var trans_level = 0;
	this._snippets = snippets;
	this._export_links = export_links ? true : false;
	do {
		P.body = P.body.replace(reTransclusion, this._transclude);
		// keep transcluding when a transclusion was made and when transcluding depth is not excessive
	} while (++trans_level < this._MAX_TRANSCLUSION_RECURSE);
	this._snippets = null;
	if (trans_level === this._MAX_TRANSCLUSION_RECURSE) { // parse remaining inclusions as normal text
		P.body = P.body.replace(reTransclusion, function (str, $1, dynamic_nl) {
			r = woas.parser.place_holder(snippets.length, "", dynamic_nl);
			snippets.push(woas.parser.render_error(str, "infin"));
			return r;
		});
	}
	this._snippets = this._export_links = null;
};

// parse passive syntax only
woas.parser.syntax_parse = function(P, snippets, tags, export_links, has_toc) {
	// put away big enough HTML tags sequences (with attributes)
	P.body = P.body.replace(/(<\/?\w+[^>]*>[ \t]*)+/g, function (tag) {
		r = woas.parser.place_holder(snippets.length);
		snippets.push(tag);
		return r;
	})
	// links with pipe e.g. [[Page|Title]]
	.replace(reWikiLink, function(str, $1, $2) {
		return woas.parser._render_wiki_link($1, $2, snippets, tags, export_links);
	})
	// links without pipe e.g. [[Page]]
	.replace(reWikiLinkSimple, function(str, $1) {
		return woas.parser._render_wiki_link($1, null, snippets, tags, export_links);
	})
	// allow non-wrapping newlines
	.replace(/\\\n/g, "")
	// underline
	.replace(/(^|[^\w])_([^_]+)_/g, "$1"+woas.parser.marker+"uS#$2"+woas.parser.marker+"uE#")
	// italics - need a space after ':'
	.replace(/(^|[^\w:])\/([^\n\/]+)\//g, function (str, $1, $2) {
		// hotfix for URLs
		if ($2.indexOf("//")!=-1)
			return str;
		return $1+"<"+"em>"+$2+"<"+"/em>";
	})
	// ordered/unordered lists parsing (code by plumloco)
	.replace(reReapLists, this.parse_lists)
	// headers - only h1~h6 are parsed
	.replace(this.reHeaders, this.header_replace);
	// other custom syntax should go into this callback
	this.extend_syntax(P);
	
	// replace [[Special::TOC]]
	if (has_toc) {
		// replace the TOC placeholder with the real TOC
		P.body = P.body.replace("<!-- "+woas.parser.marker+":TOC -->",
				"<"+"div class=\"woas_toc\"><"+"p class=\"woas_toc_title\">Table of Contents<"+"/p>" +
				this.toc.replace(reReapLists, this.parse_lists)
				/*.replace("\n<", "<") */
				+ "<"+"/div>" );
		this.toc = "";
	}

	// add a dynamic newline at start to have consistent newlines for the ruler and other syntax regex
	P.body = this.NL_MARKER + "\n" + P.body;

	// use 'strong' tag for bold text
	P.body = P.body.replace(this.reBoldSyntax, "$1"+woas.parser.marker+"bS#$2"+woas.parser.marker+"bE#")

	.replace(new RegExp(woas.parser.marker+"([ub])([SE])#", "g"), function (str, $1, $2) {
		if ($2=='E') {
			if ($1=='u')
				return "<"+"/span>";
			return "<"+"/strong>";
		}
		if ($1=='u')
			tag = "<"+"span style=\"text-decoration:underline;\">";
		else
			tag = "<"+"strong>";
		return tag;
	})

	// 'hr' horizontal rulers made with 3 hyphens, 4 suggested
	// only white spaces are allowed before/after the hyphens
	.replace(reRuler, function () {
		var n = woas.trim(arguments[0].replace(/\s+/g, " ")).split(/\ /g).length,
			last_nl;
		if (arguments[arguments.length-3].length)
			last_nl = woas.parser.NL_MARKER+arguments[arguments.length-3];
		else last_nl = "";
		return woas.parser._HR.repeat(n)+last_nl;
	})
	// tables-parsing pass
	.replace(woas.config.new_tables_syntax ? reReapTablesNew : reReapTables,
				woas.config.new_tables_syntax ? this.parse_tables_new : this.parse_tables)
	
	// cleanup \n after headers and lists
	.replace(reCleanupNewlines, function (str, $1, $2, $3, trailing_nl) {
		if (trailing_nl.length>2)
			return $1+trailing_nl.substr(2);
		return $1;
	})
	
	// remove \n before list start tags
	.replace(/\n(<[uo]l>)/g, "$1")
	
	// clear dynamic newlines
	.replace(this.reNL_MARKER, "")

	// convert newlines to br tags
	.replace(/\n/g, "<"+"br />");
	
	// put back in place all snippets
	this.undry(P, snippets);	
	snippets = null;
};

// render a single wiki link
woas.parser._render_wiki_link = function(arg1, label, snippets, tags, export_links) {
	// apply aliases to page title
	var page = woas.title_unalias(arg1),
		hashloc = page.indexOf("#"),
		gotohash = "", r,
		r_label = (label === null) ? page : label;

	// check for protocol links
	if (page.match(/^\w+:\/\//)) {
		r = woas.parser.place_holder(snippets.length);
		// convert mailto:// to mailto:
		page = page.replace(reMailto, "mailto:");
		// always give title attribute
		snippets.push("<"+"a title=\""+woas.xhtml_encode(page)+"\" class=\"woas_world_link\" href=\"" + page +
			"\" target=\"_blank\">" + r_label + "<\/a>");
		return r;
	}
	
	// check for tags definitions
	if (typeof tags == "object") {
		var found_tags = woas._get_tags(page, label);
		if (found_tags.length > 0) {
			// do not use concat because 'tags' is passed byref
			for(var i=0,it=found_tags.length;i<it;++i) {
				tags.push(found_tags[i]);
			}
			if (!this.force_inline)
				return "";
			++this.inline_tags;
			return "<!-- "+woas.parser.marker+":"+inline_tags+" -->";
		}
	}

	if (hashloc > 0) {
		if (export_links)
			gotohash = page.substr(hashloc);
		else
			gotohash = "; window.location.hash= \"" + page.substr(hashloc) + "\"";
		page = page.substr(0, hashloc);
	}

	// get a snippet id which we will later fill
	r = woas.parser.place_holder(snippets.length);
	// create a title attribute only when page URI differs from page title
	var _c_title = (page !== label) ? ' title="'+woas.xhtml_encode(page)+'"' : '', wl;
	if (hashloc === 0) { // section reference URIs
		snippets.push("<"+"a"+_c_title+" class=\"woas_link\" href=\""+page+"\">" + r_label + "<\/a>");
	} else { // normal pages
		if (woas.page_exists(page)) {
			if (export_links) {
				wl = woas.exporter._get_fname(page);
				if (wl === '#') {
					snippets.push("<"+"span class=\"woas_broken_link\">" + r_label + "<\/span>");
					return r;
				}
				wl = " href=\""+wl+"\"";
			} else
				wl = " onclick=\"woas.go_to('" + woas.js_encode(page) +"')"+gotohash+"\"";
			snippets.push("<"+"a"+_c_title+" class=\"woas_link\""+wl+">" + r_label + "<\/a>");
		} else { // unexisting pages
			if (export_links) {
				snippets.push("<"+"span class=\"woas_broken_link\">" + r_label + "<\/span>");
			} else {
				wl = " onclick=\"woas.go_to('" +woas.js_encode(page)+"')\"";
				snippets.push("<"+"a"+_c_title+" class=\"woas_unlink\" "+wl+">" + r_label + "<\/a>");
			}
		}
	} // not # at start of page
	return r;
};

// take away macros, nowiki, comments blocks
woas.parser.dry = function(P, NP, snippets) {
	// put away text in XHTML comments and nowiki blocks
	NP.body = P.body.replace(reComments, function (str, $1, dynamic_nl) {
		var r = woas.parser.place_holder(snippets.length, "", dynamic_nl);
		snippets.push(str);
		return r;
	}).replace(reNowiki, function (str, $1, dynamic_nl) {
		var r = woas.parser.place_holder(snippets.length, "", dynamic_nl);
		snippets.push(str);
		return r;
	}).replace(reMacros, function (str, $1, dynamic_nl) {
		var r = woas.parser.place_holder(snippets.length, "", dynamic_nl);
		snippets.push(str);
		return r;
	});
};

woas.parser.undry = function(NP, snippets) {
	if (!snippets.length) return;
	NP.body = NP.body.replace(this.reBaseSnippet, function (str, $1) {
		return snippets[parseInt($1)];
	});
};

/*** src/special.js ***/
woas.special_encrypted_pages = function(locked) {
	var pg = [];
	for(var i=0,l=pages.length;i < l;i++) {
		if (this.is_reserved(page_titles[i]))
			continue;
		if (locked == this.is__encrypted(i))
			pg.push(page_titles[i]);
	}
	if (!pg.length)
		return "/No locked pages found/";
	else
		return this._join_list(pg); // TODO - Delete repeated data
};

woas.special_orphaned_pages = function() {
	var pg = [],
		found = false,
		i, j, l, tmp;
	for(j=0,l=page_titles.length; j < l; j++) {
		if (this.is_reserved(page_titles[j]))
			continue;
		if (this.is_menu(page_titles[j])) {	// check if the namespace has some pages
			var ns = this.get_namespace(page_titles[j]);
			if (ns === "") continue;
			for(i=0;i < page_titles.length;i++) {
				if (page_titles[i].indexOf(ns)===0) {
					found = true;
					break;
				}
			}
		} else {
		// search for pages that link to it
			var re = new RegExp("\\[\\[" + RegExp.escape(page_titles[j]) + "(\\]\\]|\\|)", "i");
			for(i=0,l=page_titles.length; i < l; i++) {
				if ((i==j) || this.is_reserved(page_titles[i]))
					continue;
				tmp = this.get_src_page(i);
				if (tmp===null)
					continue;
				if (tmp.search(re)!=-1) {
					found = true;
					break;
				}
			}
		}
		if(found === false) {
			pg.push( page_titles[j] );
		} else found = false;
	}
	if (!pg.length)
		return "/No orphaned pages found/";
	else
		return this._join_list(pg); // TODO - Delete repeated data
};

woas.special_backlinks = function() {
	var pg = [], pg_title, tmp;
	if (this.parser.render_title === null)
		pg_title = current;
	else {
		pg_title = this.parser.render_title;
		this.parser.render_title = null;
	}
	var reg = new RegExp("\\[\\["+RegExp.escape(pg_title)+"(\\||\\]\\])", "gi");
	for(var j=0,l=pages.length; j < l; j++) {
		if (this.is_reserved(page_titles[j]))
			continue;
		// search for pages that link to it
		tmp = this.get_src_page(j);
		// encrypted w/o key
		if (tmp===null)
			continue;
		if (tmp.match(reg))
			pg.push( page_titles[j] );
	}
	if(pg.length === 0)
		return "/No page links to [["+pg_title+"]]/";
	else
		return "== Links to [["+pg_title+"]]\n"+this._join_list(pg);
};

woas._reLastSearch = null;	// search highlighting regex

woas._nearby_chars = 200;		// amount of nearby characters to display

// cached search results
woas._cached_title_search = [];
woas._cached_body_search = [];
// last string searched
woas._last_search = null;

// create an index of searched pages (by miz & legolas558)
woas._cache_search = function( str ) {
	var count = 0, tmp,
		// matches the search string and nearby text
		reg = new RegExp( ".{0,"+this._nearby_chars+"}" + RegExp.escape(this.trim(str)).
					replace(/\s+/g, "(.|\n)*?") + ".{0,"+this._nearby_chars+"}", "gi" );

	this._reLastSearch = new RegExp("("+RegExp.escape(str)+")", "gi");
	
	this._last_search = str;

	for(var i=0,l=pages.length; i < l; i++) {

		//TODO: implement searching in help pages

		if (this.is_reserved(page_titles[i]) && !this.tweak.edit_override)
			continue;

		// this could be modified for wiki searching issues
		tmp = this.get_src_page(i, true);
		if (tmp===null)
			continue;
	
		// look for string in title
		if(page_titles[i].match(reg)) {
			this._cached_title_search.push(page_titles[i]);
		}

		// look for string in body
		res_body = tmp.match(reg);
		if (res_body !== null)
			this._cached_body_search.push( { title: page_titles[i],	 matches: res_body} );
	}
};

var reFindTags = /\[\[Tags?::([^\]]+)\]\]/g;
woas.special_tagged = function(filter_string) {
	var	pg = [], folds = {"[pages]":[]}, tagns,
		src, i, l, j, jl, tmp, tag,	filtering,
		alltags;
	// filtering setup
	if (typeof filter_string != "undefined") {
		filtering = woas.tagging._prepare_filter(filter_string);
	} else filtering = false;
	// scan all pages
	for(i=0,l=pages.length;i < l;++i) {
		if (this.is_reserved(page_titles[i]))
			continue;
		src = this.get_src_page(i);
		// encrypted w/o key
		if (src === null)
			continue;
		src.replace(reFindTags, function (str, $1) {
				if (str.charAt(5) === 's')
					woas.log("Using deprecated 'Tags' namespace");
				// get the tags and index the page under each tag
				tmp=woas.split_tags($1);
				alltags = [];
				for(j=0,jl=tmp.length;j < jl; ++j) {
					tag=woas.trim(tmp[j]);
					// skip invalid tags
					if (!tag.length) {
						woas.log("WARNING: check your tag separators");
						continue;
					}
					// call the filtering callback, if necessary
					if (filtering) {
						// skip this page from listing in case of negative filter result
						if (!woas.tagging._filter_not_cb(tag))
							break;
					}
					alltags.push(tag);
				} tmp = null;
				// check that page has at least one of the positive tags
				if (filtering && !woas.tagging._filter_ok_cb(alltags))
					return;
				// add page to proper leaves
				for(j=0,jl=alltags.length;j < jl; ++j) {
					tag = alltags[j];
					// we have a valid tag, check if it is already indexed
					tagns = "Tagged::"+tag;
					if (typeof folds[tagns] == "undefined") {
						folds[tagns] = {"[pages]":[page_titles[i]]};
					} else {
//						if (folds[tagns]["[pages]"].indexOf(page_titles[i])===-1)
							folds[tagns]["[pages]"].push(page_titles[i]);
					}
					// build also the flat list - without duplicates
					if (pg.indexOf(page_titles[i])===-1)
						pg.push(page_titles[i]);
				}
			});
	} // scan pages loop
	if (filtering)
		woas.tagging._finish();
	// parse tree with sorting
	return woas.ns_listing(folds, pg, false);
};

// @module 'tagging'
woas.tagging = {
	tags_ok: null,
	tags_not: null,
	
	_finish: function() {
		this.tags_ok = this.tags_not = null;
	},

	_prepare_filter: function(filter_string) {
		var i,l, pg = [];
		// allow tags filtering/searching
		var tags = woas.split_tags(filter_string);
		// reset filter
		this.tags_ok = [];
		this.tags_not = [];
		
		// parse filter
		for(i=0,l=tags.length;i < l;++i) {
			// skip empty tags
			var tag = woas.trim(tags[i]);
			if (!tags[i].length)
				continue;
			// add a negation tag
			if (tags[i].charAt(0) === '!')
				this.tags_not.push( tags[i].substr(1) );
			else // normal match tag
				this.tags_ok.push(tags[i]);
		} tags = null;
		
		return (this.tags_ok.length + this.tags_not.length > 0);
	},
	
	// return true if all OK tag are present
	_filter_ok_cb: function(tags) {
		var ok = 0;
		if (this.tags_ok.length) {
			for(var i=0,il=tags.length;i < il;++i) {
				if (this.tags_ok.indexOf(tags[i]) !== -1)
					++ok
			}
		}
		return (ok === this.tags_ok.length);
	},

	_filter_not_cb: function(tag) {
		// filter if "NOT" tag is present
		// we are applying this filter only to tagged pages
		// so a page without tags at all does not fit into this filtering
		if (this.tags_not.length) {
			if (this.tags_not.indexOf(tag) !== -1)
				return false;
		}
		// no failure, this page passes
		return true;
	}
		
};

var reHasTags = /\[\[Tags?::[^\]]+\]\]/;
woas.special_untagged = function() {
	var tmp;
	var pg = [];
	for(var i=0,l=pages.length; i < l; i++) {
		if (this.is_reserved(page_titles[i]))
			continue;
		tmp = this.get_src_page(i);
		if (tmp === null)
			continue;
		if (!tmp.match(reHasTags))
			pg.push(page_titles[i]);
	}
	if (!pg.length)
		return '/No untagged pages/';
	return this._join_list(pg, true);
};

// Returns a index of all pages
woas.special_all_pages = function() {
	var pg = [];
	for(var i=0, l=page_titles.length; i < l; i++) {
		if (!this.is_reserved(page_titles[i]))
			pg.push( page_titles[i] );
	}
	return this._join_list(pg);
};

// Returns a index of all dead pages
var reAllWikiLinks = /\[\[([^\]\]]*?)(\|([^\]\]]+))?\]\]/g;
woas.special_dead_pages = function() {
	var dead_pages = [];
	var from_pages = [];
	var tmp, page_done;
	for(var j=0,l=pages.length;j < l;j++) {
		if (this.is_reserved(page_titles[j]) && !this.tweak.edit_override)
			continue;
		tmp = this.get_src_page(j);
		if (tmp===null)
			continue;
		page_done = false;
		tmp.replace(reAllWikiLinks,
			function (str, $1, $2, $3) {
				if (page_done)
					return false;
				var p = woas.title_unalias($1),
					sectref = p.indexOf("#");
				if (sectref === 0)
					return;
				else if (sectref > 0)
					p = p.substr(0, sectref);
				if (p.search(/^\w+:\/\//)===0)
					return;
				if (p.match(/Tag(s|ged)?:/gi))
					return;
				// skip mailto URLs
				if (p.match(/^mailto:/gi))
					return;
				if (p === "Special::TOC")
					return;
				if ((p.substr(0, 9) === "Special::") &&
					(woas.shortcuts.indexOf(p.substr(9)) !== -1))
					return;
				if (!woas.page_exists(p) && (p!==page_titles[j])) {
					// true when page has been scanned for referrals
					page_done = false;
					// check that this not-existing page is already in the deads page list
					for(var i=0;i < dead_pages.length;i++) {
						// current page contains a link to an already indexed dead page,
						// save the reference
						if (dead_pages[i]===p) {
							// add only if not already there
							if (from_pages[i].indexOf(page_titles[j]) === -1)
								from_pages[i].push(page_titles[j]);
							page_done = true;
							break;
						}
					}
					// we have just found a dead page
					if (!page_done) {
						dead_pages.push(p);
						from_pages.push(new Array(page_titles[j]));
						page_done = true;
					}
				}
	        }
		);
	}

	// format the dead pages
	var pg = [], s;
	for(var i=0;i < dead_pages.length;i++) {
		s = "[["+dead_pages[i]+"]] from ";
		var from = from_pages[i];
		for(j=0;j < from.length-1;j++) {
			s+="[["+from[j]+"]], ";
		}
		if (from.length>0)
			s+="[["+from[from.length-1]+"]]";
		pg.push(s);
	}

	woas.pager.bucket.items = dead_pages.slice(0);
	if (!pg.length)
		return '/No dead pages/';
	return this._simple_join_list(pg, true);
};

// used in Special::Options
function bool2chk(b) {
	if (b) return "checked";
	return "";
}

// Used by Special::Options
function _set_layout(fixed) {
	d$("i_woas_menu_area").style.position = d$("woas_wiki_header").style.position = (fixed ? "fixed" : "absolute");
}

//Special::Recentchanges shows a sorted list of pages by modified timestamp
woas.special_recent_changes = function() {
	if (!this.config.store_mts) {
		return "/Last modified timestamp storage is disabled in [[Special::Options]]./";
	}
	// build an array of (key := page_index, val := last_modified_timestamp) couples
	var l=page_titles.length, hm = [], i;
	for(i=0;i < l;++i) {
		// skip pages with the 'magic' zero timestamp
		if (page_mts[i] === 0)
			continue;
		// skip reserved pages which are not editable
		if (!this.edit_allowed_reserved(page_titles[i]) && this.is_reserved(page_titles[i]))
			continue;
		hm.push([i,page_mts[i]]);
	}
	// sort the array
	hm.sort(function(a,b) { return (b[1]-a[1]); });
	// display results
	var pg=[];
	for(i=0,l=hm.length;i < l;++i) {
		pg.push("* [[" + page_titles[hm[i][0]] + "]] <"+"span style=\"font-size: smaller;\">"+this.last_modified(hm[i][1])+"<"+"/span>");
	}
	if (!pg.length)
		return "/No recently modified pages/";
	return this._simple_join_list(pg);
};

woas._simple_join_list = function(arr, sorted) {
	if (sorted)
		arr = arr.sort();
	// a newline is added here
	return arr.join("\n")+"\n";
};

// joins a list of pages - always sorted by default
woas._join_list = function(arr, sorted) {
	if (!arr.length)
		return "";
	if (typeof sorted == "undefined")
		sorted = true;
	// copy the array to currently selected pages
	woas.pager.bucket.items = arr.slice(0);
	// (1) create a recursable tree of namespaces
	var ns,folds={"[pages]":[]},i,ni,nt,key;
	for(i=0,it=arr.length;i < it;++i) {
		ns = arr[i].split("::");
		// remove first entry if empty
		if (ns.length>1) {
			// in case of special menu pages
			if (ns[0].length === 0) {
//				ns.shift();
//				ns[0] = "::"+ns[0];
				// this shan't be a namespace
			} else if (ns[ns.length-1].length === 0) {
				// namespace pages, do nothing and consider them as normal pages
			} else { // pages with some namespace, recurse their namespaces and finally the page
				this.ns_recurse(ns, folds, "");
				continue;
			}
		}
		folds["[pages]"].push(arr[i]);
	}
	// (2) output the tree
	return this.ns_listing(folds, arr, sorted);
};

woas.ns_recurse = function(ns_arr, folds, prev_ns) {
	var ns = prev_ns+ns_arr.shift()+"::", item, left=ns_arr.length;;
	if (typeof folds[ns] == "undefined") {
		// last item, build the array
		if (left == 1) {
			folds[ns] = {"[pages]": [ns+ns_arr[0]] };
			return;
		}
		// namespace, create object
		folds[ns] = {"[pages]":[]};
	} else { // object already exists, add only leaves
		if (left == 1) {
			folds[ns]["[pages]"].push(ns+ns_arr[0]);
			return;
		}
	}
	if (left > 1)
		this.ns_recurse(ns_arr, folds, ns);
};

// grab expansion setting from UI radio boxes
woas._ns_expanded = function(ns, items_count, id, list_id) {
	this._ns_groups[list_id].items.push(id);
	switch (this._ns_groups[list_id].option) {
		case 1:
			return false;
		case 2:
			return true;
	}
	// ?
	return false;
};

woas._visible_css = function(v){
	return v ? "visibility: visible; display: inline" : "visibility: hidden; display: none";
};

woas.ns_recurse_parse = function(folds, output, prev_ns, recursion, sorted) {
	var i,it=folds["[pages]"].length,fold_id;
	if (it !== 0) {
		// increase recursion depth
		++recursion;
		// disable folding for pages outside namespaces
		if (prev_ns.length) {
			// generate id for folding div
			fold_id = "woas_fold"+output.fold_no++;
			var vis_css = woas._visible_css(this._ns_expanded(prev_ns, it, fold_id, output.list_id));
			output.s += "<"+"h"+(recursion+1)+" id=\""+fold_id+"_head\"> [[Javascript::d$.toggle('"+fold_id+"')|"+prev_ns+"]]";
			output.s += " [["+prev_ns+"|"+String.fromCharCode(8594)+"]] ("+it+" pages)\n<"+"/h"+(recursion+1)+">";
			output.s += "<"+"div style=\""+vis_css+"\" id=\""+fold_id+"\">\n";
		}
		// apply sorting
		if (sorted)
			folds["[pages]"].sort();
		for(i=0;i < it;++i) {
			output.s += "* [["+folds["[pages]"][i]+"]]\n";
		}
		if (prev_ns.length)
			output.s += "<"+"/div>";
	}
	// sort the actual namespaces
	if (sorted) {
		var nslist=[];
		// get namespaces
		for(i in folds) {
			if (i !== "[pages]")
				nslist.push(i);
		}
		// sort alphabetically (case insensitive)
		nslist.sort(function(x,y){
		  var a = String(x).toUpperCase();
		  var b = String(y).toUpperCase();
		  if (a > b)
			 return 1;
		  if (a < b)
			 return -1;
		  return 0;
		});
		// parse second the sorted namespaces
		it=nslist.length;
		for(i=0;i < it;++i) {
			this.ns_recurse_parse(folds[nslist[i]], output, prev_ns+nslist[i], recursion, sorted);
		}
	} else { // directly parsed without any specific sorting
		for(i in folds) {
			if (i !== "[pages]") {
				this.ns_recurse_parse(folds[i], output, prev_ns+i, recursion, sorted);
			}
		}
	}
};

// cache of current namespace listings
woas._ns_groups = {};

function _WoaS_list_expand_change(list_id, v) {
	// store selected option both in global config variable and
	// in relative list option
	woas.config.folding_style = woas._ns_groups[list_id].option = parseInt(v);
	switch (woas._ns_groups[list_id].option) {
		case 1: // collapse all
			d$.show("WoaS_"+list_id+"_folds");
			d$.hide("WoaS_"+list_id+"_flat");

			for(var i=0,it=woas._ns_groups[list_id].items.length;i < it;++i) {
				d$.hide(woas._ns_groups[list_id].items[i]);
			}
		break;
		case 0: // flat list
			d$.hide("WoaS_"+list_id+"_folds");
			d$.show("WoaS_"+list_id+"_flat");
			break;
		case 2: // expand all
			d$.show("WoaS_"+list_id+"_folds");
			d$.hide("WoaS_"+list_id+"_flat");

			for(var i=0,it=woas._ns_groups[list_id].items.length;i < it;++i) {
				d$.show(woas._ns_groups[list_id].items[i]);
			}
		break;
	}
}

woas.ns_listing = function(folds, flat_arr, sorted) {
	if (flat_arr.length === 0)
		return "/No pages in this listing/";
	if (typeof sorted == "undefined")
		sorted = false;
	var i=0;
	// do not produce the header if it is transcluded
	if (woas.parser._transcluding)
		i = 1;
	else {
		// or if this has no subnamespaces
		for(var f in folds) {
			if (i++) break;
			if (f !== "[pages]") {
				i=2;
				break;
			}
		}
	}
	var output={"s": "","fold_no":0};
	if (i!==1) {
		// this is kept here for now until some more appropriate place is individuated
		output.list_id = _random_string(8);
		// setup the group object
		this._ns_groups[output.list_id] = { "items":[], "option": woas.config.folding_style};
		output.s = "<"+"span class=\"woas_listing_options\">List view:<"+"label for=\"WoaS_"+output.list_id+"_0\"><"+"input type=\"radio\" id=\"WoaS_"+output.list_id+"_0\" name=\"WoaS_"+output.list_id+"\" value=\"0\" "+(this._ns_groups[output.list_id].option === 0 ? " checked=\"checked\"" : "" )+"onclick=\"_WoaS_list_expand_change('"+output.list_id+"',0)\">Flat<"+"/label>&nbsp;|\
	<"+"label for=\"WoaS_"+output.list_id+"_1\"><"+"input type=\"radio\" id=\"WoaS_"+output.list_id+"_1\" name=\"WoaS_"+output.list_id+"\" value=\"1\" "+(this._ns_groups[output.list_id].option === 1 ? " checked=\"checked\"" : "" )+"onclick=\"_WoaS_list_expand_change('"+output.list_id+"',1)\" >By namespace, collapsed<"+"/label>&nbsp;|\
	<"+"label for=\"WoaS_"+output.list_id+"_2\"><"+"input type=\"radio\" id=\"WoaS_"+output.list_id+"_2\" name=\"WoaS_"+output.list_id+"\" value=\"2\" "+(this._ns_groups[output.list_id].option === 2 ? " checked=\"checked\"" : "" )+" onclick=\"_WoaS_list_expand_change('"+output.list_id+"',2)\">By namespace, expanded<"+"/label>\
	<"+"/span><"+"span style=\""+woas._visible_css(this._ns_groups[output.list_id].option !== 0)+"\" id=\"WoaS_"+output.list_id+"_folds\">\n";
		
		// first fill the span for foldings
		this.ns_recurse_parse(folds, output, "", 0, sorted);
		output.s += "<"+"/span>\n"+
					"<"+"span style=\""+woas._visible_css(this._ns_groups[output.list_id].option === 0)+"\" id=\"WoaS_"+output.list_id+"_flat\">\n";
	}
	// then generate the flat list
	if (sorted)
		flat_arr.sort();
	output.s += "* [["+flat_arr.join("]]\n* [[")+"]]\n";
	if (i !== 1)
		output.s += "<"+"/span>";
	return output.s;
};

woas._special_image_gallery = function(ns) {
	var iHTML = "", snippets, P = {body:null};
	for(var i=0, l=page_titles.length;i < l;++i) {
		if (page_titles[i].indexOf(ns)===0) {
		snippets = [];
		P.body = "* "+this.parser.transclude(page_titles[i], snippets)+" [["+page_titles[i]+"]]\n";
		this.parser.syntax_parse(P, snippets);
		iHTML += P.body;
		snippets = P.body = null;
		}
	}
	return "= Pages in "+ns+" namespace\n" + iHTML;
};

/*** src/core.js ***/
// core modules

// some tweak settings NOT to be touched - warranty void otherwise
woas.tweak = {
	// DANGER: might cause WoaS corruption!
	edit_override: false,
	// perform integrity test of browser features
	integrity_test: true
};

woas.cmd_duplicate_page = function() {
	var pname = this._new_page("Insert duplicate page title", true, current+" (duplicate)");
	if (pname === null)
		return;
	var pi = this.page_index(current);
	var dpi = this.page_index(pname);
	// duplicate the page
	if (this.is__encrypted(pi)) // encrypted pages are arrays
		pages[dpi] = pages[pi].slice(0);
	else // string copy is OK
		pages[dpi] = pages[pi]; // .slice ?
	page_attrs[dpi] = page_attrs[pi];	
	// go to new page
	go_to(pname);
	// commit changes
	this.commit([dpi]);
};

woas.cmd_new_page = function() {
	this._new_page(this.i18n.INSERT_NEW, false, '');
};

// used to create a new page in the wiki
woas._new_page = function(msg, fill_mode, def_title) {
	var title = this._prompt_title(msg, def_title);
	if (title === null)
		return null;
	return this._new_page_direct(title, fill_mode);
};

// will return a valid title for a next-to-be-created page
woas._prompt_title = function(msg, def_title) {
	// disallow editing when wiki is set to read-only
	if (!this.config.permit_edits) {
		this.alert(this.i18n.READ_ONLY);
		return null;
	}
	var title = def_title;
	do {
		title = prompt(msg, title);
		if (title === null)
			break;
		title = this.trim(title);
		if (this.valid_title(title))
			break;
	} while (1);
	if ((title!==null) && title.length) {
		if (this.page_index(title)!=-1)
			this.alert(this.i18n.PAGE_EXISTS.sprintf(title));
		else
			return title;
	}
	return null;
};

woas._new_page_direct = function(title, fill_mode) {
	// properly split page title in (namespace, title) -> (ns, cr)
	var ns = this.get_namespace(title, true), cr;
	if (ns.length) {
		cr = title.substr(ns.length);
		ns = ns.substr(0, ns.length-2);
	} else cr = title;

	// check if page deserves creation
	if ((ns==="File") || (ns==="Image")) {
		go_to(title);
		return title;
	}
	// create and edit the new page
	var ct;
	if (cr !== "Menu")
		ct = "= "+cr+"\n";
	else
		ct = "\n";
	this._create_page_direct(ns, cr, fill_mode, ct);

	var upd_menu = (cr==='Menu');
	if (!upd_menu && confirm(this.i18n.ASK_MENU_LINK)) {
		var menu = this.get_text("::Menu");
		// try to put the menu link in a good position
		p = menu.indexOf("\n\n");
		if (p === -1)
			menu += "\n[["+title+"]]";
		else
			menu = menu.substring(0,p)+"\n[["+title+"]]"+menu.substring(p)+"\n";
		this.set__text(this.page_index("::Menu"), menu);
		upd_menu = true;
	}
	if (upd_menu)
		this.refresh_menu_area();
	return title;
};

// used to eventually remove the new-to-be page when cancel is pressed
woas._ghost_page = false;

woas._create_page_direct = function(ns, cr, fill_mode, default_ct) {
	// actual page creation
	pages.push(default_ct);
	if (ns.length)
		cr = ns+"::"+cr;
	page_attrs.push(0);
	page_titles.push(cr);
	// set modified timestamp
	page_mts.push(this.config.store_mts ? Math.round(new Date().getTime()/1000) : 0);
//	this.log("Page "+cr+" added to internal array");	// log:1
	if (!fill_mode) {
		// DO NOT set 'current = cr' here!!!
		// enable ghost mode when creating a new-to-be page
		this._ghost_page = true;
		this.log("Ghost page enabled"); //log:1
		// proceed with a normal wiki source page
		this.edit_page(cr);
	}
};

woas.cmd_erase_wiki = function() {
	if (this.erase_wiki()) {
		if (!this.full_commit())
			this.alert(this.i18n.FAILED_ERASE);
		back_or(this.config.main_page);
	}
	return null;
};

// pages which shall never be modified
woas.static_pages = ["Special::About", "Special::Advanced", "Special::Options","Special::Import",
						"Special::Lock","Special::Search", "Special::Embed",
						"Special::Export", "Special::License", "Special::ExportWSIF",
						"Special::ImportWSIF"];

woas.static_pages2 = ["WoaS::Plugins", "WoaS::CSS::Core",
						"WoaS::Template::Button", "WoaS::Template::Info",
						"WoaS::Template::Search", "WoaS::CSS::Boot",
						"WoaS::ImportSettings", "WoaS::Template::Example::Transclusion"];

woas.static_pages = woas.static_pages.concat(woas.static_pages2);
						
woas.help_pages = null;
woas.default_pages = ["::Menu", "WoaS::Aliases", "WoaS::Hotkeys", "WoaS::CSS::Custom"];

woas.erase_wiki = function() {
	if (!this.config.permit_edits) {
		this.alert(this.i18n.READ_ONLY);
		return false;
	}
	if (!confirm(this.i18n.CONFIRM_DELETE_ALL1) ||
		!confirm(this.i18n.CONFIRM_DELETE_ALL2))
		return false;
	var i,l,l1,l2,pi,t;
	this.progress_init("Erasing...");
	var backup_pages = [];
	// attributes and last modified timestamps for default pages
	// first entry is for main page
	page_attrs = [0]; page_mts =   [0];
	// zero is the magic timestamp
	for (i=0;i < this.default_pages.length;++i) {
		page_attrs.push(0); page_mts.push(0);
	}
	// build the array of help pages only once
	var help_pfx = "WoaS::Help::";
	if (this.help_pages === null) {
		this.help_pages = [];
		for(i=0,l=page_titles.length;i < l;++i) {
			if (page_titles[i].substr(0, help_pfx.length) === help_pfx)
				this.help_pages.push(page_titles[i].substr(help_pfx.length));
		}
	}
	var copied_help_pages = [];
	// now pick the static pages
	for(i=0,l1=this.static_pages.length,l2=this.help_pages.length,l=l1+l2;i < l;++i) {
		if (i < l1)
			t = this.static_pages[i];
		else
			t = help_pfx+this.help_pages[i-l1];
		pi = this.page_index(t);
		if (pi==-1) {
			this.alert(this.i18n.STATIC_NOT_FOUND.sprintf(t));
			continue;
		} else if (i>=l1)
			copied_help_pages.push(t);
		backup_pages.push(pages[pi]);
		// reset attributes
		page_attrs.push(0);
		// reset timestamp
		page_mts.push(0);
		this.progress_status(i/l);
	}
	// build titles
	page_titles = [ this.config.main_page ];
	page_titles = page_titles.concat(this.default_pages);
	page_titles = page_titles.concat(this.static_pages);
	page_titles = page_titles.concat(copied_help_pages);
	// now build pages
	pages = ["A blank sheet is a catalyst for ideas", "[["+this.config.main_page+"]]\n\n[[Special::All Pages]]\n[[Special::New Page]]\n[[Special::Duplicate Page]]\n[[Special::Go to]]\n[[Special::Delete Page]]\n[[Special::Backlinks]]\n[[Special::Search]]",
			"", this.hotkey._cache_default(), "/* Your CSS customization goes here */"];
	pages = pages.concat(backup_pages); backup_pages = null;
	current = this.config.main_page;
	this.refresh_menu_area();
	this.history.clear();
	// reload all extensions
	this._load_aliases(this.get_text("WoaS::Aliases"));
	this.hotkey.load(this.get_text("WoaS::Hotkeys"));
	// remove all plugins
	this.plugins.clear();
	this.plugins.load();

	this.progress_finish();
	return true;
};

woas.cmd_main_page = function() {
	go_to(this.config.main_page);
	return null;
};

// used to edit many special pages
woas.cmd_edit_special = function(cr) {
	if (!this.config.permit_edits && !this.tweak.edit_override) {
		this.alert(this.i18n.READ_ONLY);
		return null;
	}
	_servm_alert();
	// get source text (ASCII/UTF-8)
	var tmp = this.get_text(cr);
	if (tmp === null)
		return null;
	// setup the wiki editor textbox
	this.current_editing(cr, this.config.permit_edits | this._server_mode);
	this.edit_ready(tmp);
	return null;
};

woas.cmd_go_to = function() {
	// don't go anywhere if editing
	if (this.ui.edit_mode)
		return;
	var pname;
	do {
		pname = prompt("Go to page:", current);
		if ((pname !== null) && pname.length)
			if (go_to(pname))
				return;
	} while (pname !== null);
};

woas.cmd_delete = function() {
	// disallow editing when wiki is set to read-only
	if (!this.config.permit_edits) {
		this.alert(this.i18n.READ_ONLY);
		return false;
	}
	var pname = prompt(this.i18n.DELETE_PAGE_PROMPT, current);
	if ((pname === null) || !pname.length)
		return false;
	var pi = this.page_index(pname);
	if (pi == -1) {
		this.alert(this.i18n.PAGE_NOT_EXISTS+pname);
		return false;
	}
	if (this.is_reserved(pname)) {
		this.alert(this.i18n.ERR_RESERVED_NS.sprintf(this.get_namespace(pname, true)));
		return false;
	}
	if (confirm(this.i18n.CONFIRM_DELETE.sprintf(pname))) {
		this.plugins.delete_check(pname);
		this.delete_page_i(pi);
		return true;
	}
	return false;
};

// javascript shortcuts for special pages
woas.shortcuts = ["New Page", "Duplicate Page", "All Pages", "Orphaned Pages", "Backlinks",
					"Dead Pages", "Erase Wiki", "Main Page", "Go to", "Delete Page", "Recentchanges"];
woas.shortcuts_js = ["cmd_new_page", "cmd_duplicate_page", "special_all_pages", "special_orphaned_pages", "special_backlinks",
					"special_dead_pages", "cmd_erase_wiki",	"cmd_main_page", "cmd_go_to", "cmd_delete",	"special_recent_changes"];
					
woas.unexportable_pages = ["New Page", "Duplicate Page", "Backlinks", "Erase Wiki", "Edit CSS",
								"Go to", "Delete Page", "Search"];

woas.unexportable_pages2 = ["WoaS::CSS::Custom", "WoaS::CSS::Core", "WoaS::Aliases", "WoaS::Hotkeys",
							"WoaS::Plugins"];

// return raw javascript tag to be included in XHTML page
woas.raw_js = function(code) {
	return "<"+"script type=\"text/javascript\">\n"+code+"\n<"+"/s"+"cript>";
};

//API1.0: delete a page given title (without aliases)
woas.delete_page = function(title) {
	var pi = page_titles.indexOf(title);
	//DEBUG line
	if (pi === -1) {
		this.crash("Requesting deletion of unexisting page!");
		return false;
	}
	return this.delete_page_i(pi);
};

//API1.0: delete a page given absolute page index
//API1.0: @protected
woas.delete_page_i = function(i) {
	var il, old_title = page_titles[i];
//	this.log("NOTICE: deleted page "+old_title);	// log:0
	// remove the elements
	page_titles.splice(i,1);
	pages.splice(i,1);
	page_attrs.splice(i,1);
	page_mts.splice(i,1);
	// be sure that this page is no more in history
	this.history.check_deleted(old_title);
	// if we were looking at the deleted page
	if (current === old_title)
		// go to an existing page
		this.set_current(this.history.previous(), true);
	// always refresh the menu because it could contain the deleted page link
	this.refresh_menu_area();
	//TODO: send proper save notification
	return this.commit_delete([i]);
};

woas.history = {
	backstack: [],
	forstack: [],			// forward history stack, discarded when saving
	
	check_deleted: function(old_title) {
		// remove the deleted page from history
		for(var i=0,it=this.backstack.length;i < it;++i) {
			// remove also duplicate sequences
			if (this.backstack[i] === old_title) {
				this.backstack.splice(i, 1);
				// fix the loop
				--it;
				// iterate again to remove duplicate sequences
				--i;
			}
		}
		// delete also from forstack
		for(var i=0,it=this.forstack.length;i < it;++i) {
			// remove also duplicate sequences
			if (this.forstack[i] === old_title) {
				this.forstack.splice(i,1);
				// fix the loop
				--it;
				// iterate again to remove duplicate sequences
				--i;
			}
		}
		//TODO: remove subsequent duplicates in final array
	},
	
	previous: function() {
		// go back or to main page, do not save history
		if (this.backstack.length > 0) {
			return this.backstack.pop();
		} else
			return woas.config.main_page;
	},
	
	back: function() {
		if(this.backstack.length > 0) {
			this.forstack.push(current);
			return this.backstack.pop()
		}
		woas.log("No back history");
		return null;
	},
	
	has_forstack: function() {
		return (this.forstack.length > 0);
	},
	has_backstack: function() {
		return (this.backstack.length > 0);
	},
	
	_forward_browse: false,	// used when browsing forward in the page queue
	
	MAX_BROWSE_HISTORY: 6,
	
	go: function(title) {
		if (!this._forward_browse) {
			this.store(title);
			// reset forward stack
			this.forstack = [];
		} else this._forward_browse = false;
	},
	
	// push a page into history
	store: function(page) {
		if (this.backstack.length > this.MAX_BROWSE_HISTORY)
			this.backstack = this.backstack.slice(1);
		this.backstack.push(page);
	},
	
	forward: function() {
		if(this.forstack.length > 0)
			return this.forstack.pop();
		woas.log("No forward history");
		return null;
	},
	
	clear: function() {
		this.forstack = [];
		this.backstack = [];
	}

};

woas.history.backstack = backstack;

// some general integrity tests - for debug purposes
woas.integrity_test = function() {
	woas.log("Starting integrity test"); //log:1
	// test integrity of data arrays
	var len = pages.length;
	if ((page_attrs.length != len) ||
			(page_titles.length != len) ||
			(page_mts.length != len)) {
			this.crash("FATAL: data arrays have mismatching length!\n"+
						"#pages = %d, #page_attrs = %d, #page_titles = %d, #page_mts = %d".
						sprintf(pages.length, page_attrs.length, page_titles.length,
						page_mts.length));
		return false;
	}
	// test integrity of ecma encoding for normal UTF-8
	var UTF8_TEST = "Di\u00e2critics are here: \u00e4 \u00e1y";
	if (this.ecma_decode(this.ecma_encode(UTF8_TEST)) !== UTF8_TEST) {
		this.crash("ECMA encoding not working:\n"+this.ecma_decode(this.ecma_encode(UTF8_TEST))+
		"\n"+UTF8_TEST);
		return false;
	}
	// test integrity of ecma encoding for 16bit UTF-8
	var UTF8_TEST2 = "\u30e9\u30c9\u30af\u30ea\u30d5";
	if (this.ecma_decode(this.ecma_encode(UTF8_TEST2)) !== UTF8_TEST2) {
		this.crash("ECMA encoding/decoding not working:\n"+this.ecma_decode(this.ecma_encode(UTF8_TEST2))+
		"\n"+UTF8_TEST2);
		return false;
	}
	// test integrity of load/save functions if not on remote server
	if (!this._server_mode) {
		if (!this.save_file(woas.ROOT_DIRECTORY+"itest.bin", this.file_mode.UTF8_TEXT,
				woas.utf8.encode(UTF8_TEST)
	//			UTF8_TEST
				)) {
			this.crash("Save failure during integrity test\n"+woas.ROOT_DIRECTORY);
			return false;
		}
		var ct = this.load_file(woas.ROOT_DIRECTORY+"itest.bin", this.file_mode.UTF8_TEXT);
		if ((ct === null)||(ct === false)) {
			if (ct === false)
				this.crash("Load failure during integrity test\n"+woas.ROOT_DIRECTORY);
			return false;
		}
		ct = woas.utf8.decode(ct);
		if (ct !== UTF8_TEST) {
			this.crash("UTF8 test failed.\nWritten:\n"+UTF8_TEST+"\nRead:\n"+ct);
			return false;
		}
	} else { // we are on a remote server
		woas.log("Skipping save integrity test because running from web server");	//log:1
		//TODO: remote load integrity test
	}
	// now test AES encryption
	woas.AES.setKey("WoaS");
	var testdata = "sample text here";
	var enc = woas.AES.encrypt(testdata);
	if (woas.AES.decrypt(enc) !== testdata) {
		this.crash("AES encryption is not working two-way!");
		woas.AES.clearKey();
		return false;
	}
	if (woas.AES.decrypt(woas.AES.encrypt(UTF8_TEST)) !== UTF8_TEST) {
		this.crash("AES encryption of UTF8 text is not working two-way!");
		woas.AES.clearKey();
		return false;
	}
	woas.AES.clearKey();
	woas.log("Integrity test successful"); //log:1
	return true;
};

// used in path normalization during export
woas.DIRECTORY_SEPARATOR = (navigator.appVersion.indexOf("Win")!=-1)?"\\":"/";

woas._dirname_regex = new RegExp("\\"+woas.DIRECTORY_SEPARATOR+"[^\\"+woas.DIRECTORY_SEPARATOR+"]*$");
woas._basename_regex = new RegExp("[\\\\/]([^\\\\/]+)$");		// "\\[\\\\/]([^\\\\/]+)$"

// hackish functions, might stay private for now
woas.dirname = function(fn) {
	return fn.replace(this._dirname_regex, woas.DIRECTORY_SEPARATOR);
};

woas.basename = function(fn) {
	var m = fn.match(this._basename_regex);
	if (m === null)
		return fn;
	return m[1];
};

// the export path used by export feature
woas.ROOT_DIRECTORY = woas.dirname(_get_this_filename());

//API1.0: get page attributes - can be overriden by plugins
//TODO: all code should use this function
woas.get_page_attrs = function(pi) {
	// no error check
	return page_attrs[pi];
};

//API1.0: set page attributes - can be overriden by plugins
//TODO: all code should use this function
woas.set_page_attrs = function(pi, attrs) {
	// no error check
	page_attrs[pi] = attrs;
	return true;
};

//API1.0: dynamically add a hotkey
// returns true if hotkey was added successfully or if already present
woas.add_hotkey = function(key, function_obj) {
	//FIXME: this needs to be finished!
};

woas.split_bytes = function(s) {
	var l=s.length;
	var arr=[];
	for(var i=0;i < l;i++)
		arr.push(s.charCodeAt(i));
	return arr;
};
	
woas.merge_bytes = function(byte_arr) {
	var l=byte_arr.length, s="";
	for(var i=0;i < l;i++) {
		s+=String.fromCharCode(byte_arr[i]);
	}
	return s;
};

var reReplaceBr = new RegExp("<"+"br\\s?\\/?>", "gi");
woas.xhtml_to_text = function(s) {
	return s.replace(reReplaceBr, "\n").replace(/<\/?\w+[^>]*>/g, ' ').
					replace(/&#?([^;]+);/g, function(str, $1) { if (!isNaN($1)) return String.fromCharCode($1); else return ""; });
};

// WoaS DOM manager
// all DOM modifications shall be indexed by this module
woas.dom = {
	// hashmap used to quickly reference some important DOM objects
	_cache: {},
	// DOM management area
	_objects: [],
	
	init: function() {
		this._cache.head = document.getElementsByTagName("head")[0];
		this._cache.body = document.getElementsByTagName("body")[0];
		if (woas.browser.ie)
			this._cache.stylesheet = document.styleSheets[0];
		else
			this._cache.stylesheet = document.getElementsByTagName("style")[0];
	},
	
	add_css: function(css_id, css_src, external, after_load) {
/*		if (document.createStyleSheet) {// check for MSIE
			this._cache.head.insertAdjacentHTML('beforeEnd',
				'<'+'span id="'+'" style="display:none">x<'+'/span>'  // MSIE needs this for some reason
				+ '<+'style id="'+'" type="text/css">'+css_text+'<'+'/style>');
			//TODO: check that style can then be properly removed
		  } else { */
		// always add this custom prefix
		css_id = "woas_css_"+css_id;
		
		// check if we have a duplicate instance
		if (this.index(css_id) !== -1) {
			woas.log("DOM: instance "+css_id+" already exists");
			return false;
		}
		
		var style;
		if (external) {
			style = document.createElement("link");
			style.setAttribute("rel", "stylesheet");
			style.setAttribute("type", "text/css");
			style.setAttribute("id", css_id);
			style.setAttribute("href", css_src);
			// only when external
			++this._loading;
		} else {
			style = document.createElement('style');
			style.type = "text/css";
			style.id = css_id;
			style.appendChild(document.createTextNode(css_text));
		}
		
		this._objects.push( {obj:style, parent: (woas.browser.ie ? this._cache.body:this._cache.head),
							instance:css_id, after_load: external ? after_load : null } );
		
		woas.log("DOM: "+css_id+" created "+this._show_load());
		// add a callback which informs us of the completion (not always possible)
		if (external) {
			// these engines don't support a callback :(
			if (woas.browser.gecko || woas.browser.webkit) {
				setTimeout("woas.dom._elem_onload('"+woas.js_encode(css_id)+"');", 100);
			} else { // good ol' IE
				style.onreadystatechange = woas._make_delta_func("woas.dom._elem_onload",
													"'"+woas.js_encode(css_id)+"'");
			}
		}
		
		// on IE inject directly in body
		if (woas.browser.ie) {
			this._cache.body.appendChild(style);
		} else {
			this._cache.head.appendChild(style);
		}
		return true;
	},
	
	remove_css: function(i) {
		return this.remove("woas_css_"+i);
	},

	remove_script: function(script_class, script_id) {
		return this.remove("woas_script_"+script_class+"_"+script_id);
	},
	
	remove: function(instance) {
		var found = this.index(instance);
		if (found === -1)
			return false;
		// delete DOM entry from parent container
		this._objects[found].parent.removeChild(this._objects[found].obj);
		// fix arrays
		this._objects.splice(found, 1);
		return true;
	},
	
	// counter of elements being loaded
	_loading: 0,
	
	// generic callback used when we want to run something after the file has been loaded
	// (usually CSS/JavaScript)
	_elem_onload: function(instance) {
		// go away if it is already loaded
		if (woas.dom.get_loaded(instance))
			return;
		// only for IE
		if (woas.browser.ie && (typeof this.readyState != "undefined")) {
			if (this.readyState != 'complete' && this.readyState != 'loaded')
				return;
			// remove handler
			this.onreadystatechange = null;
		} else if (woas.browser.firefox) {
		  // unplug handler
		  var dom_obj = woas.dom._objects[woas.dom.index(instance)];
		  dom_obj.obj.onload = null;
		}
		// set as loaded (shall not remove from arrays)
		woas.dom.set_loaded(instance);
	},
	
	get_loaded: function(instance) {
		var i = this.index(instance);
		if (i !== -1) {
			if (this._objects[i].instance === instance)
				return this._objects[i].loaded;
		}
		woas.log("DOM: "+instance+" is not indexed"+this._show_load());
		return false;
	},
	
	// get list of instances which are still loading
	get_loading: function() {
		var a=[];
		for(var i=0,it=this._objects.length;i < it;++i) {
			if (!this._objects[i].loaded)
				a.push(this._objects[i].instance);
		}
		return a;
	},
	
	// short-hand to get index of an instance
	index: function(instance) {
		for(var i=0,it=this._objects.length;i < it;++i) {
			if (this._objects[i].instance === instance)
				return i;
		}
		return -1;
	},

	set_loaded: function(instance) {
		var i = this.index(instance);
		if (i !== -1) {
			this._objects[i].loaded = true;
				
			// now call the associated callback
			if (typeof this._objects[i].after_load == "function") {
				(this._objects[i].after_load)();
			}
			
			// reduce the counter of 'hung' requests
			--this._loading;
			woas.log("DOM: "+instance+" completed loading"+this._show_load());
			// check if we need to launch the hook
			if (this._loading === 0)
				this._run_post_load_hook();
			
			return true;
		}
		woas.log("DOM: "+instance+" completed loading, but was not indexed"+this._show_load());
		return false;
	},
	
	_show_load: function() {
		return "";
		return " (%d/%d)".sprintf(this._loading, this._objects.length)+"\n"+
				"still loading: "+this.get_loading();
	},
	
	// regex used to remove some comments
	reJSComments: /^\s*\/\*[\s\S]*?\*\/\s*/g,
	
	_internal_add: function(script_token, script_content, external, after_load) {
		script_token = "woas_script_"+script_token;
		// check if we have a duplicate instance
		if (this.index(script_token) !== -1) {
			woas.log("DOM: instance "+script_token+" already exists");
			return false;
		}
		
		var s_elem = document.createElement("script");
		s_elem.type="text/javascript";
		s_elem.id = script_token;

		// register in our management arrays
		this._objects.push( {obj:s_elem, parent:this._cache.head, instance:script_token,
								external: external ? true : false,
								loaded: external ? false : true, after_load: external ? after_load : null} );
		// only external sources should be marked as "loading"
		if (external)
			++this._loading;
		woas.log("DOM: "+script_token+" created "+(external ? "("+script_content+") ":"(inline) ")+this._show_load());
		// add a callback which informs us of the completion
		if (external) {
			if (woas.browser.ie)
				s_elem.onreadystatechange = woas._make_delta_func("woas.dom._elem_onload",
													"'"+woas.js_encode(s_elem.id)+"'");
			else
				s_elem.onload = woas._make_delta_func("woas.dom._elem_onload",
													"'"+woas.js_encode(s_elem.id)+"'");
			// specify the external URL
			s_elem.src = script_content;
		}
				
		this._cache.head.appendChild(s_elem);
		if (!external) {
//			woas.alert("Inline code:\n"+script_content);
			woas.setHTML(s_elem, script_content);
		}
		return true;
	},
	
	add_script: function(script_class, script_id, script_content, external, after_load) {
		// remove the comments
		if (!external)
			script_content = script_content.replace(this.reJSComments, '');
		// it's not necessary to add this script tag
		if (!script_content.length) return false;
		return this._internal_add(script_class+"_"+script_id, script_content, external, after_load);
	},
	
	// remove all script objects
	remove_all: function() {
		var it=this._instances.length;
		for(var i=0;i < it;++i) {
			// remove the object
			this._objects[i].parent.removeChild(this._objects[i].obj);
		}
		// clear objects array
		this._objects = [];
	},
	
	// call the argument function when there aren't other libraries left to load
	// returns true if loading was already complete
	// returns false if we are async-waiting
	_post_load_hook: woas._dummy_fn,
	wait_loading: function(fn_object) {
		if (this._loading === 0) {
			(fn_object)();
			// always reset associated async hook
			this._post_load_hook = woas._dummy_fn;
			return true;
		}
		// associate the hook
		this._post_load_hook = fn_object;
		return false;
	},
	
	_run_post_load_hook: function() {
		// run in a thread so that the call to last object unload does not wait on the hook
		setTimeout('woas.dom._post_load_hook();woas.dom._post_load_hook=woas._dummy_fn;', 10);
	}
	
};

// generate a delta function and cache it
woas._delta_cache = {};
woas._make_delta_func = function(fn_name, fn_args) {
	var id=fn_name+' '+fn_args;
	var fn_obj;
	if (typeof woas._delta_cache[id] == "undefined") {
		eval("fn_obj = function() { "+fn_name+"("+fn_args+"); };");
		woas._delta_cache[id] = fn_obj;
	} else
		fn_obj = woas._delta_cache[id];
	return fn_obj;
};

// @module pager
woas.pager = {

	_decrypt_failed: false,	// the last decryption failed due to wrong password attempts
	
	decrypt_failed: function() {
		if (this._decrypt_failed) {
			this._decrypt_failed = false;
			return true;
		}
		return false;
	},

	get: function(title) {
		return woas.get_text(title);
	},
	
	get_by_index: function(i) {
		return woas.get__text(i);
	},
	
	// this yummy function needs can be overriden
	browse_hook: function(title) {
		return true;
	},
	
	// set content of specified page
	set_body: function(title, new_body) {
		var pi = woas.page_index(title);
		if (woas.debug_mode) {
			if (pi === -1) {
				woas.log("BUG: page \""+title+"\" does not exist!");	// log:1
				return;
			}
		}
		woas.set__text(pi, new_body);
	}
};

// @module pager.bucket
woas.pager.bucket = {
	items: [],		// multi-pages selection
	clear: function() {
		this.items = [];
	},
	add: function(title) {
		if (this.items.indexOf(title) === -1)
			this.items.push(title);
	},
	// used when we want to set a single page in bucket
	one: function(title) {
		this.items = [title];
	}
};

// namespace for custom stuff defined by macros/plugins
// if you are a JavaScript developer you should put singleton instance objects in here
woas.custom = { };

/*** src/stickwiki.js ***/
// the namespace(+subnamespaces) of the current page
woas.current_namespace = "";

// the last page on which the cached AES key was used on
woas.last_AES_page = "";

// tells if configuration has been changed
woas.cfg_changed = false;

// new variables will be properly declared here
woas.prev_title = current;		// previous page's title used when entering/exiting edit mode

woas.save_queue = [];		// pages which need to be saved and are waiting in the queue

// Auto-Save Thread
woas._autosave_thread = null;

// previous length of WSIF datasource
woas._old_wsif_ds_len = null;

// this will likely happen when javascript code block was corrupted
woas._on_load = woas_on_unload = function() { this.crash("Deferred load/unload function not available!");};

// default post-load hook
woas.post_load = function(){};

// left and right trim
// grabbed from http://blog.stevenlevithan.com/archives/faster-trim-javascript
woas.trim = function(str) {
//	return s.replace(/(^\s*)|(\s*$)/, '');
	str = str.replace(/^\s+/, '');
	for (var i = str.length - 1; i >= 0; i--) {
		if (/\S/.test(str.charAt(i))) {
			str = str.substring(0, i + 1);
			break;
		}
	}
	return str;
};

// used to craft XHTML pages
woas.DOCTYPE = "<"+"!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n";
woas.DOC_START = "<"+"html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n<"+"head>\n"+
	"<"+"meta woas_permanent=\"1\" http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n";

// general javascript-safe string quoting
// NOTE: not completely binary safe!
// should be used only for titles (which ought not to contain binary bytes)
var reMinorG = new RegExp("<", "g");
woas.js_encode = function (s, split_lines) {
	// not to counfound browsers with saved tags
	s = s.replace(/\\/g, "\\\\").replace(reMinorG, "\\x3C").replace(/>/g, "\\x3E").
		replace(/'/g, "\\'");
	// escape newlines (\r\n happens only on the stupid IE) and eventually split the lines accordingly
	if (!split_lines)
		s = s.replace(new RegExp("\r\n|\n", "g"), "\\n");
	else
		s = s.replace(new RegExp("\r\n|\n", "g"), "\\n\\\n");
	return this._utf8_js_fix(s);
};

// perform ECMAScript encoding only on some UTF-8 sequences
woas.ecma_encode = function(s) {
	return this._utf8_js_fix(s.replace(/\\/g, "\\\\"));
};

woas._ecma_rx_test = new RegExp("[^\u0000-\u007F]");

// returns true if text needs ECMA encoding
// checks if there are UTF-8 characters
woas.needs_ecma_encoding = function(s) {
	return this._ecma_rx_test.test(s);
};

woas._utf8_js_fix = function(s) {
	// fix the >= 128 ascii chars (to prevent UTF-8 characters corruption)
	return s.replace(woas.utf8.reUTF8Space, function(str) {
		var r="";
		for(var a=0,l=str.length;a < l;++a) {
			var s = str.charCodeAt(a).toString(16);
			r += "\\u" + "0000".substr(s.length) + s;
		}
		return r;
	});
};

woas.ecma_decode = function(s) {
	return s.replace(new RegExp("(\\\\u[0-9a-f]{4})+", "g"), function (str, $1) {
		// this will perform real UTF-8 decoding
		var r = "";
		for (var ic=0,totc=str.length;ic < totc;ic+=6) {
			// get the hexa-numeric part
			var c = str.substr(ic+2, 4);
			// remove leading zeroes and convert to base10
			c = parseInt(c.replace(/^0*/,''), 16);
			// convert UTF-8 sequence to character
			r += String.fromCharCode(c);
		}
		return r;
	}).replace(/\\\\/g, "\\");
};

// used to escape blocks of source into HTML-valid output
woas.xhtml_encode = function(src) {
/*	return this.utf8.do_escape(src.replace(/[<>&]+/g, function ($1) {
		var l=$1.length;
		var s="";
		for(var i=0;i < l;i++) {
			switch ($1.charAt(i)) {
				case '<':
					s+="&lt;";
					break;
				case '>':
					s+="&gt;";
					break;
//				case '&':
				default:
					s+="&amp;";
			}
		}
		return s;
	})); */
	return this.utf8.do_escape(src.replace(/&/g, '&amp;').replace(reMinorG, '&lt;').
			replace(/>/g, '&gt;')); // .replace(/"/g, '&quot;').replace(/'/g, '&#39;');
};

// DO NOT modify this list! these are namespaces that are reserved to WoaS
var reserved_namespaces = ["Special", "Lock", "Locked", "Unlocked", "Unlock",
						"Tags" /*DEPRECATED*/,
						"Tagged", "Untagged", "Include", "Javascript",
						"WoaS"];

// create the regex for reserved namespaces
var reserved_rx = "^";
for(var i = (woas.tweak.edit_override ? 1 : 0);i < reserved_namespaces.length;i++) {
	reserved_rx += /*RegExp.Escape(*/reserved_namespaces[i] + "::";
	if (i < reserved_namespaces.length-1)
		reserved_rx += "|";
}
woas._reserved_rx = new RegExp(reserved_rx, "i"); reserved_namespaces = reserved_rx = null;

// return page index (progressive number) given its title
woas.page_index = function(title) {
	return page_titles.indexOf(this.title_unalias(title));
};

woas.is_reserved = function(page) {
	return (page.search(this._reserved_rx)==0);
};

woas.is_menu = function(title) {
	return (title.substr(title.length-6) === "::Menu");
};

// returns namespace with trailing ::
woas.get_namespace = function(page, root_only) {
	var p;
	if ((typeof root_only == "boolean") && (root_only == true))
		p = page.indexOf("::");
	else
		p = page.lastIndexOf("::");
	if (p==-1) return "";
	return page.substring(0,p+2);	
};

// page attributes bits are mapped to (readonly, encrypted, ...)

woas.is_readonly = function(page) {
	return this.is_readonly_id(this.page_index(page));
};

woas.is_readonly_id = function(pi) {
	return !!(page_attrs[pi] & 1);
};

woas.is__encrypted = function (pi) {
	return !!(page_attrs[pi] & 2);
};

woas.is_encrypted = function(page) {
	return this.is__encrypted(this.page_index(page));
};

woas.is__embedded = function(pi) {
	return !!(page_attrs[pi] & 4);
};
woas.is_embedded = function(page) {return this.is__embedded(this.page_index(page));};

woas.is__image = function(pi) {
	return !!(page_attrs[pi] & 8);
};
woas.is_image = function(page) { return this.is__image(this.page_index(page)); };

// a page physically exists if it is not part of a reserved namespace, if it is not a (sub)namespace and if it actually exists
woas.page_exists = function(page) {
	return (this.is_reserved(page) || (page.substring(page.length-2)==="::") || (this.page_index(page)!==-1));
};

// with two trailing double colon
woas._get_namespace_pages = function (ns) {
	var pg = [];
	switch (ns.substr(0, ns.length-2)) {
		case "Locked":
			return this.special_encrypted_pages(true);
		case "Unlocked":
			return this.special_encrypted_pages(false);
		case "Untagged":
			return this.special_untagged();
		case "Tagged": // to be used in wiki source
			return this.special_tagged();
		case "Image":
			return this._special_image_gallery(ns);
	}

	for(i=0, l=page_titles.length;i < l;++i) {
		if (page_titles[i].indexOf(ns)===0)
			pg.push(page_titles[i]);
	}
	return /*"= Pages in "+ns+" namespace\n" + */this._join_list(pg);
};

// return a plain page or a decrypted one if available through the latest key
woas.get_page = function(pi) {
	if (this.is__embedded(pi))
		return null;
	if (!this.is__encrypted(pi))
		return pages[pi];
	if (!this.AES.isKeySet()) {
		this.last_AES_page = "";
		return null;
	}
	// decrypt by using a copy of the array
	var pg = this.AES.decrypt(pages[pi].slice(0));
	this.last_AES_page = page_titles[pi];
	return pg;	
};

var reScriptTags = new RegExp("<"+"script[^>]*>((.|\\n)*?)<"+"\\/script>", "gi"),
	reAnyXHTML = /\<\/?\w+[^>]+>/g;
// get the text of the page, stripped of html tags
woas.get_src_page = function(pi, rawmode) {
	var pg = this.get_page(pi);
	if (pg===null) return null;
	if ((typeof rawmode == "undefined") || (rawmode == false))
		pg = pg.replace(/\{\{\{((.|\n)*?)\}\}\}/g, "");
	else
		pg = pg.replace(/(\{|\})(\1)(\1)/g, "$1<"+"!-- -"+"->$2<"+"!-- -"+"->$3");
	// remove wiki and html that should not be viewed when previewing wiki snippets
	return pg.replace(reScriptTags, "").
			replace(reAnyXHTML, "");
};

woas.get_text = function (title) {
	var pi = this.page_index(title);
	if (pi==-1)
		return null;
	return this.get__text(pi);
};

woas.get_text_special = function(title) {
	var ns = this.get_namespace(title);
	var text = null;
	if (ns.length) {
//		woas.log("namespace of "+title+" is "+namespace);	// log:0
		title = title.substring(ns.length);
		if (!title.length) return this._get_namespace_pages(ns);
		switch (ns) {
			case "Special::":
				text = this._get_special(title, false);
				if (text === false) text = null;
			break;
			case "Tagged::":
				text = this.special_tagged(title);
			break;
			default:
				text = this.get_text(ns+title);
		}
	} else
		text = this.get_text(title);
	return text;
};

woas.__last_title = null;

woas.__password_finalize = function(pwd_obj) {
	d$.show_ni("woas_wiki_area");
	document.title = this.__last_title;
	d$.hide("woas_pwd_mask");
//	scrollTo(0,0);
	// hide input form
	pwd_obj.value = "";
	pwd_obj.blur();
	this.ui.blur_textbox();
};

woas._set_password = function() {
	this.__last_title = document.title;
	document.title = "Enter password";
	// hide browser scrollbars and show mask
	d$.show("woas_pwd_mask");
	d$.hide_ni("woas_wiki_area");
	scrollTo(0,0);
	// show input form
	d$.show_ni("woas_pwd_query");
	d$("woas_password").focus();	
	this.ui.focus_textbox();
};

woas._password_cancel = function() {
	this.__password_finalize(d$("woas_password"));
};

woas._password_ok = function() {
	var pwd_obj = d$("woas_password");
	var pw = pwd_obj.value;
	if (!pw.length) {
		this.alert(this.i18n.PWD_QUERY);
		return;
	}
	this.AES.setKey(pw);
	this.__password_finalize(pwd_obj);
};

//TODO: specify interactive-mode
woas.get__text = function(pi) {
	// is the page encrypted or plain?
	if (!this.is__encrypted(pi))
		return pages[pi];
	this.pager._decrypt_failed = true;
	if (!this.AES.isKeySet()) {
		this.alert(this.i18n.ERR_NO_PWD.sprintf(page_titles[pi]));
		return null;
	}
	this.progress_init("AES decryption");
//	var pg = null;
			//TODO: use form-based password input
//			this._get_password('The latest entered password (if any) was not correct for page "'+page_titles[pi]+"\"");
//			var pw = prompt('The latest entered password (if any) was not correct for page "'+page_titles[pi]+"'\n\nPlease enter the correct password.", '');
//			if ((pw==null) || !pw.length) {
			// we are waiting for the password to be set programmatically
/*			if (!pw.length) {
				this.last_AES_page = "";
				AES_clearKey();
				document.body.style.cursor = "auto";
				return null;
			}
			AES_setKey(pw);
			retry++;
*/
//			return null;
//		}
		// pass a copied instance to the decrypt function
		// AES_decrypt can return null on failure, but can also return a garbled output
		var pg = this.AES.decrypt(pages[pi].slice(0));
		this.last_AES_page = page_titles[pi];
//		if (pg != null)
//			break;
	if (!this.config.key_cache)
		this.AES.clearKey();
	if (pg !== null) {
		this.pager._decrypt_failed = false;
//		if (this.config.key_cache)			this.last_AES_page = page_titles[pi];
	} else {
		this.alert(this.i18n.ACCESS_DENIED.sprintf(page_titles[pi]));
//		AES_clearKey();
		this.last_AES_page = "";
	}
	this.progress_finish();
	return pg;
};

woas.set__text = function(pi, text) {
	this.log("Setting wiki text for page #"+pi+" \""+page_titles[pi]+"\"");	// log:1
	if (this.is__embedded(pi) && !this.is__image(pi))
		text = this.base64.encode(text);
	if (!this.is__encrypted(pi)) {
		pages[pi] = text;
		return;
	}
	pages[pi] = this.AES.encrypt(text);
	this.last_AES_page = page_titles[pi];
};

woas.assert_current = function(page) {
	if( current !== page )
		go_to( page ) ;
	else
		this.set_current( page, true);
};

woas._get_embedded = function(cr, etype) {
	var pi = this.page_index(cr);
	if (pi === -1) {
		var P = {body:this.parser.transclude("Special::Embed|"+etype, [])};
		this.parser.syntax_parse(P, []);
		return P.body;
	}
	return this._get__embedded(cr, pi, etype);
};

woas._get__embedded = function (cr, pi, etype) {
	var text=this.get__text(pi);
	if (text==null) return null;
	var xhtml = "";
	
	if (etype=="file") {
		var fn = cr.substr(cr.indexOf("::")+2);
		var pview_data = this.base64.decode(text, 1024), pview_link = "",
			ext_size = Math.ceil((text.length*3)/4);
		//FIXME: is this even correct?
		if (ext_size-pview_data.length>10)
			pview_link = "<"+"div id='_part_display'><"+"em>"+this.i18n.FILE_DISPLAY_LIMIT+
			"<"+"/em><"+"br /><"+"a href='javascript:show_full_file("+pi+")'>"+this.i18n.DISPLAY_FULL_FILE+"<"+"/a><"+"/div>";
		var P = {body: "\n{{{[[Include::"+cr+"]]}}}"+
				"\n\nRaw transclusion:\n\n{{{[[Include::"+cr+"|raw]]}}}"};
		if (!this.is_reserved(cr))
			P.body += "\n\n\n<"+"a href=\"javascript:query_delete_file('"+this.js_encode(cr)+"')\">"+this.i18n.DELETE_FILE+"<"+"/a>\n";
		P.body += "\n";
		
		// correct syntax parsing of nowiki syntax
		var snippets = [];
		this.parser.pre_parse(P, snippets);
		this.parser.syntax_parse(P, snippets);
		this.parser.undry(P, snippets);
		
		xhtml = "<"+"pre id='woas_file_ct' class=\"woas_nowiki woas_embedded\">"+this.xhtml_encode(pview_data)+"<"+"/pre>"+
				pview_link+"<"+"br /><"+"hr />"+this.i18n.FILE_SIZE+": "+_convert_bytes(ext_size)+
				"<"+"br />" + this.last_modified(this.config.store_mts ? page_mts[pi] : 0)+
				"<"+"br /><"+"br />XHTML transclusion:"+
				P.body +
				"<"+"a href=\"javascript:query_export_file('"+this.js_encode(cr)+"')\">"+this.i18n.EXPORT_FILE+"<"+"/a><"+"br />";
		P = null;
	} else { // etype == image
		var img_name = cr.substr(cr.indexOf("::")+2);
		//TODO: do not create a dynamic script! use after_parse hook
		xhtml = this.parser.parse("= "+img_name+"\n\n"+
		"<"+"script type=\"text/javascript\"> setTimeout(\"_img_properties_show('"+
				text.match(/^data:\s*([^;]+);/)[1] + "', "+
				text.length + ", " +
				(text.match(/^data:\s*[^;]*;\s*[^,]*,\s*/)[0]).length+", "+
				(this.config.store_mts ? page_mts[pi] : 0 ) +
				")\");"+
		"<"+"/script>"+
		"<"+"img id=\"woas_img_tag\" class=\"woas_embedded\" src=\""+text+"\" alt=\""+this.xhtml_encode(img_name)+"\" />"+
		"\n\n<"+"div id=\"woas_img_desc\">"+this.i18n.LOADING+"<"+"/div>"+
		"\nSimple transclusion:\n\n{{{[[Include::"+cr+"]]}}}\n\nTransclusion with additional attributes:\n\n{{{[[Include::"+cr+"|border=\"0\" onclick=\"go_to('"+
		this.js_encode(cr)+"')\" style=\"cursor:pointer\"]]}}}\n"+
		"\n<"+"a href=\"javascript:query_delete_image('"+this.js_encode(cr)+"')\">"+this.i18n.DELETE_IMAGE+"<"+"/a>\n"+
		"\n<"+"a href=\"javascript:query_export_image('"+this.js_encode(cr)+"')\">"+this.i18n.EXPORT_IMAGE+"<"+"/a>\n");
	}
	return xhtml;
};

woas._embed_process = function(etype) {
	// pick the correct mode for file inclusion
	// normalize etype to the correspondant binary flag value
	var desired_mode;
	if (etype == "image") {
		desired_mode = this.file_mode.DATA_URI;
		etype = 12;
	} else {
		desired_mode = this.file_mode.BASE64;
		etype = 4;
	}
	
	// load the data in DATA:URI mode
	var ct = this.load_file(null, desired_mode);
	if ((ct === false) || ((typeof ct != "string") || !ct.length)) {
		this.alert(this.i18n.LOAD_ERR);
		return false;
	}
	
	pages.push(ct);
	page_attrs.push(etype);
	page_titles.push(current);
	// set modified timestamp to now
	page_mts.push(this.config.store_mts ? Math.round(new Date().getTime()/1000) : 0);
	
	// save this last page
	this.commit(page_titles.length-1);
	
	this.refresh_menu_area();
	return this.set_current(current, true);
};

woas._get_special = function(cr, interactive) {
	var text = null;
	var pi = this.shortcuts.indexOf(cr);
	cr = "Special::" + cr;
	if (pi != -1) {
		var fn = this.shortcuts_js[pi];
		var is_cmd = (fn.substr(0,4)=="cmd_");
		if (!interactive && is_cmd)
			return null;
		text = this[fn]();
		// skip the cmd shortcuts
		if (is_cmd)
			// return a special value for executed commands
			return false;
	} else
		text = this.get_text(cr);
	if(text === null) {
		if (interactive)
			this.alert(this.i18n.INVALID_SPECIAL);
	}
	return text;
};

// this is quite undocumented
woas.get_javascript_page = function(cr) {
	var emsg = "-", text;
	text = woas.eval(cr, true);
	if (this.eval_failed) {
		this.crash("Dynamic evaluation of '"+cr+"' failed!\n\nError message:\n\n"+this.eval_fail_msg);
		return null;
	}
	// for safety
	if ((typeof text).toLowerCase() != "string")
		return null;
	return text;
};

woas.eval = function(code, return_value) {
	var rv;
	try {
		if (return_value)
			eval("rv = "+code);
		else
			eval(code);
		woas.eval_failed = false;
	}
	catch (e) {
		this.eval_fail_msg = e.toString();
		this.eval_failed = true;
	}
//	woas.log("woas.eval(\""+code+"\", "+return_value+") = "+rv);	//log:0
	return rv;
};

// Load a new current page
// return true if page needs to be saved in history, false otherwise
woas.set_current = function (cr, interactive) {
	// call hooks which decide upon our navigation capabilities
	if (!woas.pager.browse_hook(cr))
		return false;
//	this.log("Setting current page to \""+cr+"\"");	//log:0
	var text, namespace, pi,
		// whether to reset bucket or not
		set_b = false;
	woas.pager.bucket.clear();
	// eventually remove the previous custom script
	if (cr.substring(cr.length-2)==="::") {
		text = this._get_namespace_pages(cr);
		namespace = cr.substring(0,cr.length-2);
		cr = "";
	} else {
		var p = cr.indexOf("::");
		// skip not found references but also null namespace references
		if (p>0) {
			namespace = cr.substring(0,p);
//			this.log("namespace of "+cr+" is "+namespace);	// log:0
			cr = cr.substring(p+2);
				switch (namespace) {
					case "Javascript":
					// this namespace may deprecate many others
					text = this.get_javascript_page(cr);
					if (text === null)
						return false;
					break;
					case "Special":
						text = this._get_special(cr, interactive);
						//the 'false' special value is returned in case of command execution
						if (text === false)
							return true;
						// no such special page exists
						if (text === null)
							return false;
						break;
					case "Tagged":
						text = this.special_tagged(cr);
						if (text === null)
							return false;
						break;
					case "Lock":
						// prevent special pages from being locked
						if (this.is_reserved(cr)) {
							this.alert(this.i18n.CANNOT_LOCK_RESERVED);
							return false;
						}
						pi = this.page_index(cr);
						if (this.AES.isKeySet()) {
							// display a message
							if (confirm(this.i18n.CONFIRM_LOCK.sprintf(cr)+
								(this.last_AES_page ? this.i18n.CONFIRM_LOCK_LAST.sprintf(last_AES_page) : ''))) {
								this._finalize_lock(pi);
								return false;
							}
						}
						text = this.get_text("Special::Lock");
						break;
					case "Unlock":
						pi = this.page_index(cr);
						if (!confirm(this.i18n.CONFIRM_REMOVE_ENCRYPT.sprintf(cr)))
							return false;
						text = this.get_text(cr);
						if (this.pager.decrypt_failed())
							return false;
						pages[pi] = text;
						page_attrs[pi] -= 2;
						if (!this.config.key_cache)
							this.AES.clearKey();
						if (this.set_current(cr, true)) {
							this.save_page(cr);
							return true;
						}
						return false;
					case "WoaS":
						pi = woas.page_index(namespace+"::"+cr);
						// unexisting page
						if (pi === -1)
							return false;
						var real_t = page_titles[pi];
/*						if (this.is__embedded(pi)) {
							//TODO: do not use namespace to guess the embedded file type
							text = this._get__embedded(real_t, pi, "file");
						} else { */
						// detect if showing a plugin
						var _pfx = "WoaS::Plugins::";
						if (real_t.substr(0, _pfx.length) === _pfx) {
							text = this.plugins.get(real_t.substr(_pfx.length));
							if (text !== null) {
								if (this.plugins.is_external) {
									text = this.plugins.describe_external(text);
								} else
									text = this._raw_preformatted('div', text, 'woas_core_page woas_nowiki woas_nowiki_multiline');
							}
						} else {
							text = this.get_text(real_t);
							if (text !== null) {
								switch (cr) {
									case "Plugins":
										text = this.parser.parse(text + this.plugins.list());
									break;
									case "Aliases":
									case "Hotkeys":
										case "CSS::Core":
									case "CSS::Boot":
									case "CSS::Custom":
										// page is stored plaintext
										text = this._raw_preformatted('div', text, 'woas_core_page woas_nowiki woas_nowiki_multiline');
									break;
									default:
										// help pages and related resources
										text = this.parser.parse(text);
								} // switch per page title
							} // text not null
						} // plugins/non-plugins

						if(text === null) {
							// called for reset purposes
							this.pager.decrypt_failed();
							return false;
						}
						this._add_namespace_menu(namespace);
						if (namespace.length)
							cr = real_t;
						return this.load_as_current(cr, text, this.config.store_mts ? page_mts[pi] : 0, true);
					case "File":
					case "Image":
						text = this._get_embedded(namespace+"::"+cr, namespace.toLowerCase());
						if(text === null) {
							// called for reset purposes
							this.pager.decrypt_failed();
							return false;
						}
						this._add_namespace_menu(namespace);
						if (namespace.length)
							cr = namespace + "::" + cr;
						var mts;
						if (this.config.store_mts)
							mts = page_mts[this.page_index(namespace+"::"+cr, namespace.toLowerCase())];
						else mts = 0;
						return this.load_as_current(cr, text, mts, true);
					default:
						text = this.get_text(namespace+"::"+cr);
						set_b = true;
				}

		} else {
			namespace = "";
			text = this.get_text(cr);
			set_b = true;
		}
	}
	
	// action taken when no such page exists (or decryption failed)
	if (text === null) {
		if (this.pager.decrypt_failed())
			return false;
		return this._new_page(this.i18n.PAGE_NOT_FOUND, false, namespace.length ? namespace+ "::"+ cr : cr);
	}
	
	this._add_namespace_menu(namespace);

	// hard-set the current page to the namespace page
	if (namespace.length) {
		cr = namespace + "::" + cr;
		pi = this.page_index(cr);
		if (pi)
			mts = page_mts[pi];
		else mts = null;
	} else {
		pi = this.page_index(cr);
		cr = page_titles[pi];
		mts = page_mts[pi];
	}
	// used by some special pages (e.g. backlinks) for page title override
	return this.load_as_current(cr, this.parser.parse(text, false, this.js_mode(cr)), this.config.store_mts ? mts : 0, set_b);
};

// enable safe mode for non-reserved pages
woas.js_mode = function(cr) {
	if (this.config.safe_mode)
		return this.is_reserved(cr) ? 1 : 3;
//	else
	return 1;
};

woas.last_modified = function(mts) {
	// do not show anything when the timestamp is magic (zero)
	if (mts == 0)
		return "";
	return this.i18n.LAST_MODIFIED + (new Date(mts*1000)).toLocaleString();
};

// actually load a page given the title and the proper XHTML
woas.load_as_current = function(title, xhtml, mts, set_b) {
	if (typeof title == "undefined") {
		this.crash("load_as_current() called with undefined title");
		return false;
	}
	
	// used by some special pages (e.g. backlinks) for page title override
	this.parser.render_title = title;
	// the bucket will contain only the rendered page
	if (set_b)
		this.pager.bucket.one(title);

	
	scrollTo(0,0);
	this.log("load_as_current(\""+title+"\", "+set_b+") - "+(typeof xhtml == "string" ? (xhtml.length+" bytes") : (typeof xhtml)));	// log:1
	this.setHTMLDiv(d$("woas_wiki_area"), xhtml);
	this.refresh_mts(mts);

	this._set_title(title);
	
	this.history.go(current);
	
	this.update_nav_icons(title);
	current = title;
	// active menu or page scripts
	this.scripting.activate(this.is_menu(current) ? "menu" : "page");
	return true;
};

woas._finalize_lock = function(pi) {
	this._perform_lock(pi);
	var title = page_titles[pi];
	this.set_current(title, true);
	if (!this.config.key_cache) {
		this.AES.clearKey();
		this.last_AES_page = "";
	} else
		this.last_AES_page = title;
	this.save_page_i(pi);
};

woas._perform_lock = function(pi) {
	pages[pi] = this.AES.encrypt(pages[pi]);
	page_attrs[pi] += 2;
};

woas._add_namespace_menu = function(namespace) {
	if (this.current_namespace === namespace)
		return;
	var pi;
	if (namespace === "")
		pi = -1;
	else // locate the menu for current namespace
		pi = this.page_index(namespace+"::Menu");
	if (pi === -1) {
//		this.log("no namespace menu found");	// log:0
		this.setHTMLDiv(d$("woas_ns_menu_area"), "");
		if (this.current_namespace !== "") {
			d$.hide("woas_ns_menu_area");
			d$.hide("woas_ns_menu_edit_button");
		}
		this.current_namespace = namespace;
		return;
	}
	var menu = this.get__text(pi);
	this.setHTMLDiv(d$("woas_ns_menu_area"), menu === null ? "" : this.parser.parse(menu, false, this.js_mode(namespace+"::Menu")) );
	// show sub-menu
	d$.show("woas_ns_menu_area");
	d$.show("woas_ns_menu_edit_button");
	this.current_namespace = namespace;	
};

// auto-save thread
woas._auto_saver = function() {
	if (woas.save_queue.length && !woas.ui.edit_mode) {
		woas.commit(woas.save_queue);
		woas.menu_display("save", false);
	}
	// always clear previous thread
	clearTimeout(woas._autosave_thread);
	// re-launch the thread
	if (_this.config.auto_save)
		woas._autosave_thread = setTimeout("woas._auto_saver()", woas.config.auto_save);
};

// save configuration on exit
woas._on_unload = function () {
	if (this.save_queue.length)
		this.commit(this.save_queue);
	else {
		if (this.config.save_on_quit && this.cfg_changed)
			this.cfg_commit();
	}
	return true;
};

 // DO NOT use setHTML for the document.body object in IE browsers
woas.setHTML = woas.getHTML = null;

// these are unchanged for all browsers
woas.getHTMLDiv = function(elem) {return elem.innerHTML;};
woas.setHTMLDiv = function(elem, html) {elem.innerHTML = html;};

// when the page is loaded - onload, on_load
woas._on_load = function() {
	// output platform information - note that revision is filled in only in releases
	woas.log("*** WoaS v"+this.version+"-r2239"+" started");	// log:1
	
	// store the old length to eventually force full save when entering/exiting WSIF datasource mode
	this._old_wsif_ds_len = this.config.wsif_ds.length;

	// (0) set some browser-tied functions
	if (this.browser.ie) {	// some hacks for IE
		this.setHTML = function(elem, html) {elem.text = html;};
		this.getHTML = function(elem) {return elem.text;};
		var obj = d$("woas_wiki_header");
		obj.style.filter = "alpha(opacity=75);";
		if (this.browser.ie6) {
			d$("woas_wiki_header").style.position = "absolute";
			d$("i_woas_menu_area").style.position = "absolute";
		}
		// IE6/7 can't display logo
		if (!this.browser.ie8) {
			d$.hide("img_logo");
			// replace with css when capability exists:
			d$("woas_logo").style.width = "1%";
		}
	} else {
		this.setHTML = this.setHTMLDiv;
		this.getHTML = this.getHTMLDiv;
		// everyone else needs a logo; will be better when done in css.
		d$("woas_logo").style.width = "35px";
		d$.show("img_logo");
	}
	
	// (1) check integrity of WoaS features - only in debug mode
	if (this.config.debug_mode) {
		this._set_debug(true);
		if (this.tweak.integrity_test) {
			if (!this.integrity_test())
				// test failed, stop loading
				return;
		}
	} else
		this._set_debug(false);

	// (2) load the actual pages (if necessary)
	if (this.config.wsif_ds.length) {
		if (!this._wsif_ds_load(this.config.wsif_ds, this.config.wsif_ds_lock)) {
			// the file load error is already documented to user
			if (this.wsif.emsg !== null) {
				// force debug mode
				this._set_debug(true);
				this.crash("Could not load WSIF pages data!\n"+this.wsif.emsg);
			}
			return;
		}
	}

	// (3) setup some DOM cage objects (read cache)
	this.dom.init();

	// (4) activate the CSS, with eventual fixups for some browsers
	this.css.set(this.get_text("WoaS::CSS::Core")+"\n"+this.get_text("WoaS::CSS::Custom"));
	
	// (5) continue with UI setup
	d$('woas_home_hl').title = this.config.main_page;
	d$('img_home').alt = this.config.main_page;
	
	// properly initialize navigation bar icons
	// this will cause the alternate text to display on IE6/IE7
	var nav_bar = ["back", "forward", "home", "edit", "print", "advanced",
					"cancel", "save", "lock", "unlock", "setkey", "help",
					"top", "debug"];
	for(var i=0,it=nav_bar.length;i < it;++i) {
		this.img_display(nav_bar[i], true);
	}
	
	// customized keyboard hook
	document.onkeydown = woas.ui._keyboard_event_hook;
	
	// Go straight to requested page
	var qpage=document.location.href.split("?")[1];
	if (qpage) {
		current = unescape(qpage);
		// extract the section (if any)
		var p=current.indexOf("#");
		if (p !== -1)
			current = current.substring(0,p);
	}
	
	// (6) initialize extensions - plugins go first so that external javascript/CSS
	// starts loading
	this.setHTML(d$("woas_wait_text"), "Initializing extensions...");
	this.plugins.load();
	this._load_aliases(this.get_text("WoaS::Aliases"));
	this.hotkey.load(this.get_text("WoaS::Hotkeys"));

	if (this.config.permit_edits)
		d$.show("menu_edit_button");
	else
		d$.hide("menu_edit_button");
	
	// enable the auto-save thread
	if (this.config.cumulative_save && this.config.auto_save)
		this._autosave_thread = setTimeout("woas._auto_saver()", this.config.auto_save);
	
	this._editor = new TextAreaSelectionHelper(d$("woas_editor"));

	this.setHTML(d$("woas_wait_text"), "Completing load process...");
	
	// set a hook to be called when loading process is complete
	if (!woas.dom.wait_loading(woas._early_render))
		woas._load_hangup_check(true);
};

// the first page rendering is a delicate process
// plugins and related libraries/CSS must be loaded
// before rendering the first page to prevent some glitches
// to happen, like: missing CSS, missing macros etc
woas._dummy_fn = function() { return; };
woas._load_hangup_check = function(first) {
	// first time we just re-create the spawning thread
	if (!first) {
		if (!woas.dom._loading) {
			woas.log("_load_hangup_check() finished");
			return
		}
		// ask user if he wishes to continue waiting for libraries to finish loading
		if (!confirm(this.i18n.CONTINUE_WAIT_LOAD)) {
			// run the hook like if nothing hung up
			woas.dom._run_post_load_hook();
			woas.log("_load_hangup_check() cancelled");
			return;
		}
	}
	// launch again this thread, every 3s
	woas.log("_load_hangup_check() respawned (still loading: "+woas.dom.get_loading()+")");
	setTimeout("woas._load_hangup_check(false);", 3000);
};
	
woas._early_render = function() {
	woas.history._forward_browse = true; // used to not store backstack
	woas.set_current(current, true);
	woas.refresh_menu_area();
	// feed the current title before running the disable edit mode code
	woas.prev_title = current;
	woas.disable_edit();
	
//	this.progress_finish();
	d$.hide("loading_overlay");
	
	// launching post-load hook
	woas.post_load();	
};

// disable edit-mode after cancel/save actions
woas.disable_edit = function() {
//	woas.log("DISABLING edit mode");	// log:0
	this.ui.edit_mode = false;
	// reset change buffer used to check for page changes
	this.change_buffer = null;
	this.old_title = null;
	// check for back and forward buttons - TODO grey out icons
	this.update_nav_icons(current);
	this.menu_display("home", true);
	if (this.config.cumulative_save)
		this.menu_display("save", (this.save_queue.length!==0));
	else
		this.menu_display("save", false);
	this.menu_display("cancel", false);
	this.menu_display("print", true);
	this.menu_display("setkey", true);
	d$.show("i_woas_text_area");
	// aargh, FF eats the focus when cancelling edit
	d$.hide("edit_area");
	this._set_title(this.prev_title);
};

function _lock_pages(arr) {
	this.alert("Not yet implemented");
}

function _unlock_pages(arr) {
	this.alert("Not yet implemented");
}

woas.edit_allowed = function(page) {
	// can always edit pages if they have an actual data representation
	if (this.tweak.edit_override)
		return (this.page_index(page) != -1);
	// force read-only
	if (!this.config.permit_edits)
		return false;
	if (this.edit_allowed_reserved(page))
		return true;
	// page in reserved namespace
	if (this.is_reserved(page))
		return false;
	// page has readonly bit set
	return !this.is_readonly(page);
};

woas.edit_allowed_reserved = function(page) {
	var _pfx = "WoaS::Plugins::";
	if (page.substr(0, _pfx.length) === _pfx)
		return true;
	// allow some reserved pages to be directly edited/saved
	switch (page) {
		case "WoaS::Aliases":
		case "WoaS::Hotkeys":
		case "WoaS::CSS::Custom":
			return true;
	}
	return false;
};

// setup the title boxes and gets ready to edit text
woas.current_editing = function(page, disabled) {
//	woas.log("current = \""+current+"\", current_editing(\""+page+"\", disabled: "+disabled+")");	// log:0
	this.prev_title = current;
	d$("wiki_page_title").disabled = (disabled && !this.tweak.edit_override ? "disabled" : "");
	d$("wiki_page_title").value = page;
	this.ui.edit_mode = true;
	this._set_title(this.i18n.EDITING.sprintf(page));
	// current must be set BEFORE calling enabling menu edit
//	woas.log("ENABLING edit mode");	// log:0
	this.menu_display("back", false);
	this.menu_display("forward", false);
	this.menu_display("advanced", false);
	this.menu_display("setkey", false);
	this.menu_display("home", false);
	this.menu_display("edit", false);
	this.menu_display("print", false);
	this.menu_display("save", true);
	this.menu_display("cancel", true);
	this.update_lock_icons(page);
	d$.hide("i_woas_text_area");

	// FIXME! hack to show the editor pane correctly on IE
	if (!this.browser.ie) {
		d$("woas_editor").style.width = window.innerWidth - 35 + "px";
		d$("woas_editor").style.height = window.innerHeight - 180 + "px";
	} else {
		d$("woas_editor").style.width = document.documentElement.clientWidth - 35 + "px";
		d$("woas_editor").style.height = document.documentElement.clientHeight - 180 + "px";
	}
	d$.show("edit_area");

	d$("woas_editor").focus();
	current = page;
	scrollTo(0,0);
};

woas.change_buffer = null;
woas.old_title = null;

// sets the text and allows changes monitoring
woas.edit_ready = function (txt) {
	d$("woas_editor").value = txt;
	// save copy of text to check if anything was changed
	// do not store it in case of ghost pages
	this.change_buffer = txt;
	this.old_title = d$("wiki_page_title").value;
};

woas.edit_page = function(page) {
	// can't edit again if already editing
	if (this.ui.edit_mode)
		return false;
	if (!this.edit_allowed(page)) {
		woas.log("Not allowed to edit page "+page);	// log:1
		return false;
	}
	_servm_alert();
	var tmp = this.get_text(page);
	if (tmp===null) return false;
	if (this.is_embedded(page) && !this.is_image(page))
		tmp = this.base64.decode(tmp);
	// setup the wiki editor textbox
	this.current_editing(page, this.is_reserved(page));
	this.edit_ready(tmp);
	return true;
};

//API1.0: check if a title is valid
woas.valid_title = function(title) {
	if (title.length == 0) {
		this.alert(this.i18n.EMPTY_TITLE);
		return false;
	}
	if (title.length > 256) {
		this.alert(this.i18n.TOO_LONG_TITLE.sprintf(256));
		return false;
	}
	if (title.indexOf("[")!==-1 || title.indexOf("]")!==-1 ||
		title.indexOf("{")!==-1 || title.indexOf("}")!==-1 ||
		title.indexOf("<") !== -1 || title.indexOf(">")!==-1 ||
		title.indexOf("|")!==-1 || title.indexOf(":::")!==-1) {
		this.alert(this.i18n.INVALID_TITLE);
		return false;
	}
	if (title.substr(-2)==="::") {
		this.alert(this.i18n.ERR_PAGE_NS);
		return false;
	}
	var ns = this.get_namespace(title, true);
	if (ns.length && this.is_reserved(ns+"::") && !this.tweak.edit_override) {
		this.alert(this.i18n.ERR_RESERVED_NS.sprintf(ns));
		return false;
	}
	return true;
};

woas.rename_page = function(previous, newpage) {
	woas.log("Renaming "+previous+" to "+newpage);	// log:1
	if (this.page_index(newpage)!=-1) {
		this.alert(this.i18n.PAGE_EXISTS.sprintf(newpage));
		return false;
	}
	// this is the actual rename operation
	var pi = this.page_index(previous);
	page_titles[pi] = newpage;
	// variables used to change all occurrencies of previous title to new title
	var reTitles = new RegExp("\\[\\[(Include::)?" + RegExp.escape(previous) + "(\\]\\]|\\|)", "g"),
		// the original page (dried)
		P = {body:null},
		// the expanded
		NP = {body:null},
		changed,
		snippets,
		ilen;
	for(var i=0,l=pages.length;i < l;i++) {
		P.body = this.get_page(i);
		if (P.body === null)
			continue;
		changed = false;
		snippets = [];
		// the parser will know what to take away from the page
		this.parser.dry(P, NP, snippets);
		// replace direct links and transclusion links
		NP.body = NP.body.replace(reTitles, function (str, inc) {
			changed = true;
			ilen = 2 + inc.length;
			return str.substr(0, ilen)+newpage+str.substr(previous.length+ilen);
		});
		if (changed) {
			// clear dynamic newlines
			NP.body = NP.body.replace(this.parser.reNL_MARKER, "");
			this.parser.undry(NP, snippets);
			this.set__text(i, NP.body);
		}
		P.body = NP.body = snippets = null;
	}
	if (previous === this.config.main_page)
		this.config.main_page = newpage;
	// make sure that previous title is consistent
	if (this.prev_title === previous)
		this.prev_title = newpage;
	//TODO: propagate rename to backstack and forstack!
	return true;
};

woas.get_raw_content = function() {
	var c=d$("woas_editor").value;
	// remove CR added by some browsers
	//TODO: check if ie8 still adds these
	if (this.browser.ie || this.browser.opera)
		c = c.replace("\r\n", "\n");
	return c;
};

// action performed when save is clicked
woas.save = function() {
	// you can't save if not editing
	if (!this.ui.edit_mode)
		return false;
	// we will always save ghost pages if save button was hit
	var null_save = !this._ghost_page, was_ghost = this._ghost_page;
	// always reset ghost page flag
	this._ghost_page = false;
	woas.log("Ghost page disabled"); //log:1
	// when this function is called in non-edit mode we perform a full commit
	// for cumulative save
	if (this.config.cumulative_save && !this.ui.edit_mode) {
		this.full_commit();
		this.menu_display("save", false);
		return;
	}
	var raw_content = this.get_raw_content();
	
	// check if this is a null save only if page was not a ghost page
	if (null_save)
		null_save = (raw_content === this.change_buffer);
	
	var can_be_empty = false, skip = false, renaming = false;
	switch(current) {
		case "WoaS::CSS::Custom":
			if (!null_save) {
				this.css.set(this.get_text("WoaS::CSS::Core")+"\n"+raw_content);
				this.pager.set_body(current, raw_content);
			}
			back_to = this.prev_title;
			break;
		case "WoaS::Aliases":
			if (!null_save)
				this._load_aliases(raw_content);
			can_be_empty = true;
			// fallback wanted
			skip = true;
		case "WoaS::Hotkeys":
			if (!skip && !null_save)
				this.hotkey.load(raw_content);
			// fallback wanted
		default:
			// check if text is empty (page deletion)
			if (!null_save && !can_be_empty && (raw_content === "")) {
				if (confirm(this.i18n.CONFIRM_DELETE.sprintf(current))) {
					this.plugins.delete_check(current);
					this.delete_page(current);
					this.disable_edit();
					back_or(this.config.main_page);
				}
				return;
			} else {
				var new_title = this.trim(d$("wiki_page_title").value);
				renaming = (this.old_title !== new_title);
				// do not glitch when creating a new page
				if (was_ghost)
					this.prev_title = new_title;
				// here the page gets actually saved
				if (!null_save || renaming) {
					// disallow empty titles
					if (renaming && !this.valid_title(new_title))
						return false;
					// rename before eventually setting the changes
					if (renaming) {
						if (!this.rename_page(this.old_title, new_title))
							return false;
					}
					// actually set text only if it was changed
					if (!null_save)
						this.pager.set_body(new_title, raw_content);
					var maybe_plugin;
					if (this.is_menu(new_title)) {
						if (renaming || !null_save) {
							this.refresh_menu_area();
							back_to = this.prev_title;
						}
						maybe_plugin = false;
					} else {
						back_to = new_title;
						maybe_plugin = true;
					}
					// update the plugin if this was a plugin page
					// NOTE: plugins are not allowed to be renamed, so
					// old title is equal to new title
					if (maybe_plugin) {
						var _pfx = "WoaS::Plugins::";
						if (new_title.substr(0, _pfx.length) === _pfx) {
							// we do not directly call _update_plugin because
							// plugin does not exist before creation so disabling it
							// would fail
							this.plugins.disable(new_title.substr(_pfx.length));
							this.plugins.enable(new_title.substr(_pfx.length));
						}
					}
				} else { // not renaming and not changed text
					back_to = this.prev_title;
					// do not glitch when creating a new page
				}
			}
	}

	var saved = current;
//	if (back_to !== null)
		this.set_current(back_to, true);
/*	else { // used for CSS editing
		back_or(this.config.main_page);
		//TODO: refresh mts?
	} */
	if (!null_save || renaming)
		this.refresh_menu_area();
	this.disable_edit();
	if (!null_save || renaming)
		this.save_page(saved);
};

woas.save_page = function(title) {
	return this.save_page_i(this.page_index(title));
};

woas.save_page_i = function(pi) {
	// update the modified time timestamp (only when not in dev-mode)
	if (!this.tweak.edit_override)
		page_mts[pi] = this.config.store_mts ? Math.round(new Date().getTime()/1000) : 0;
	// this is the dummy function that will allow more efficient file saving in future
	if (this.config.cumulative_save) {
		// add the page to the bucket, if it isn't already in
		if (!this.save_queue.length) {
			this.save_queue.push(pi);
			this.menu_display("save", true);
		} else {
			if (this.save_queue.indexOf(pi)==-1)
				this.save_queue.push(pi);
		}
		woas.log("save_queue = ("+this.save_queue+")");	// log:1
		return true;
	}
	return this.commit([pi]);
};

woas.create_breadcrumb = function(title) {
	var tmp=title.split("::");
	if (tmp.length===1)
		return title;
	var s="", partial="", js="";
	for(var i=0;i < tmp.length-1;i++) {
		// editing is active
		if (this.ui.edit_mode)
			s+= tmp[i]+" :: ";
		else {
			partial += tmp[i]+"::";
			js = "go_to('"+this.js_encode(partial)+"')";
			s += "<"+"a title=\""+this.xhtml_encode(tmp[i])+"\" href=\"javascript:"+js+"\" onclick=\""+js+"; return false;\">"+tmp[i]+"<"+"/a> :: ";
		}
	}
	// add page title
	return s+tmp[tmp.length-1];
};

/*** src/extensions.js ***/
// @module scripting
// @description manages custom scripts declared in menu and main page
// All custom scripts can be defined in one of the two
woas.scripting = {
	menu: [],	// scripts active in menu
	page: [],	// scripts active in page
	_menu_stacked: 0,	// number of elements which shall be cleared
	_page_stacked: 0,	// ''
	
	// remove all scripts from specified array (can be 'menu' or 'page')
	clear: function(which) {
		for(var i=0;i < this["_"+which+"_stacked"];++i) {
			woas.dom.remove_script(which, i);
		}
		this["_"+which+"_stacked"] = 0;
	},
	
	// add a custom script for later activation
	add: function(which, content, external) {
		this[which].push([content, external]);
	},
	
	activate: function(which) {
		for(var i=0;i < this[which].length;++i) {
			if (woas.dom.add_script(which, i, this[which][i][0], this[which][i][1]))
				++this["_"+which+"_stacked"];
		}
		// free memory
		this[which] = [];
	},
	
	remove: function(which, index) {
		if (woas.dom.remove_script(which, index)) {
			--this["_"+which+"_stacked"];
			return true;
		}
		return false;
	}
	
};

// @module 'plugins'
woas.plugins = {
	
	// flag set by last call to get()
	is_external: false,
	_all: [],
	_active: [],	// list of enabled plugins
	
	get: function(name) {
		this.is_external = false;
		var text = woas.pager.get("WoaS::Plugins::"+name);
		// check if this is an external page reference
		if (name.charAt(0) === '@') {
			// hack for external files loading at run-time
			// each source file specified in a new line as a definition with flags for different browsers
			var uris = this._parse_external(text);
			if (uris !== null) {
				// we got it
				this.is_external = true;
				text = uris;
			}
		}
		return text;
	},
	
	_parse_external: function(text) {
		var uris=[], uri_def, p, sb;
		text = text.split("\n");
		for(var i=0;i < text.length;++i) {
			uri_def = woas.trim(text[i]);
			if (!uri_def.length)
				continue;
			// check this URI for validity
			p = uri_def.indexOf("=");
			if (p === -1)
				continue;
			sb = this._craft_object(uri_def.substr(p+1));
			if (sb === null) // no mode was activated by this definition
				continue;
			sb.src = woas.trim(uri_def.substr(0,p));
//			woas.log(sb.src+" " +sb.is_inline+" "+sb.is_async);
			// finally add it to basket
			uris.push(sb);
		}
		if (uris.length == 0)
			woas.log("no valid source URIs found");
		return uris;
	},
	
	reIncludeDef: new RegExp("([\\+@])(\\*|([a-zA-Z0-9_]+)(\\([0-9\\.]+[-\\+]?\\))?)", "g"),
	
	// parse definitions for browser include type
	_craft_object: function(s) {
		var sb = {
			is_inline: false,
			is_async: false
		}, inline_init = false, async_init = false;
		s.replace(this.reIncludeDef, function(str, sym, full_browser_str,browser_str, version) {
			// a handy shortcut
			switch (browser_str) {
				case "ff":
					browser_str = "firefox";
				break;
				// not supported
				case "ie6": case "ie8": case "firefox2": case "firefox3": case "firefox_new":
					woas.log("Invalid browser token: "+browser_str);
					return;
			}
			// check the catch-all case
			if (full_browser_str === '*') {
				if (sym === '+') {
					if (!inline_init) {
						inline_init = sb.is_inline = true;
					} else woas.log("Ignored catch-all inline because a restricting criteria was already specified");
				} else { // if (sym === '@')
					if (!async_init) {
						async_init = sb.is_async = true;
					} else woas.log("Ignored catch-all async because a restricting criteria was already specified");
				}
				return;
			}
			// check that this browser token is valid
			var t = typeof woas.browser[browser_str];
			if (t == "undefined") {
				woas.log("Invalid browser token: "+browser_str);
				return;
			}
			// parse the symbol if that browser token is active and version matches
			if (woas.browser[browser_str]) {
				// make a version check only if necessary
				var its_ok = false;
				if (version.length !== 0) {
					// check that we have a version string, before all
					if (t != "string") {
						woas.log("No version string for browser token \""+browser_str+"\"");
						return;
					}
					// remove parenthesis
					version = version.substr(1, version.length-2);
					// check the last character
					var lc = version.charAt(version.length-1);
					if (lc === '+') { // match version and above
						its_ok = (woas.strnatcmp(woas.browser[browser_str], version) >= 0);
					} else if (lc === '-') { // match version and below
						its_ok = (woas.strnatcmp(woas.browser[browser_str], version) <= 0);
					} else { // plain version match
						its_ok = (woas.strnatcmp(woas.browser[browser_str], version) == 0);
					}
				} else its_ok = true;
				// version was not OK
				if (!its_ok) return;
				// operate the operator
				if (sym === '+') {
					sb.is_inline = true;
					sb.is_async = false;
					inline_init = true;
				} else {
					sb.is_async = true;
					sb.is_inline = false;
					async_init = true;
				}
			}
			// continue with next token
		});
		// if nothing was specified, fail
		if (!inline_init && !async_init) return null;
		return sb;
	},

	// disable one single plugin
	disable: function(name) {
		var i = this._active.indexOf(name);
		if (i !== -1) {
			_mapped_name = this._mapping(name);
			// attempt removing the script block and fail otherwise
			if (!woas.dom.remove("plugin", _mapped_name))
				return false;
			// external plugin, try to remove the lib blocks created
			if (name.charAt(0) === '@') {
				var p = this.get(name);
				if (this.is_external && (p.length>1)) { // *special* external plugins
					for(var i=0;i < p.length;++i) {
						woas.dom.remove_script("lib", _mapped_name+'_'+i);
					}
				}
			}
			this._active.splice(i, 1);
			return true;
		}
		return false;
	},

	update: function(name) {
		return this.disable(name) && this.enable(name);
	},
	
	_internal_add: function(name, s) {
		if (s.is_async) {
			if (woas.dom.add_script("plugin", this._mapping(name), s.src, true)) {
				this._active.push( name );
				return true;
			}
		} else /*if (s.is_inline) */ { // create an inline javascript (slower)
			var ct = woas.load_file(woas.ROOT_DIRECTORY+woas.fix_path_separators(s.src)),
				t = (typeof ct);
			// write some nice message
			if (t.toLowerCase() != "string") {
				woas.log("could not load inline javascript source "+s.src);
				return false;
			} else {
				// add the inline block
				if (woas.dom.add_script("plugin", this._mapping(name), ct, false)) {
					this._active.push( name );
					return true;
				}
			}
		}
		// failed adding DOM script
		return false;
	},

	// enable a single plugin
	enable: function(name) {
		if (this._active.indexOf(name) !== -1) {
			woas.log("BUG: Plugin "+name+" is already active");
			return true;
		}
		// generate the script element
		var p = this.get(name);
		if (this.is_external) { // *special* external plugins
			// single reference, do not create script block
			if (p.length === 1) {
				return this._internal_add(name, p[0] );
			} else {
				var js="";
				for(var i=0;i < p.length;++i) {
					if (p[i].is_async)
						js += 'woas.dom.add_script("lib", "'+this._mapping(name)+'_'+i+"\", \""+woas.js_encode(p[i].src)+"\", true);\n";
					else /*if (p[i].is_inline) */ {
						var ct = woas.load_file(woas.ROOT_DIRECTORY+woas.fix_path_separators(p[i].src)),
							t = (typeof ct);
						// write some nice message
						if (t.toLowerCase() !== "string")
							js += "/* woas.load_file(\"::/"+p[i].src+"\") returned "+ct+" ("+t+") */\n";
						else {
							// add the loaded code
							js += ct; ct = null;
						}
					} // no other symbols for now
				} //efor
				// finally add the real script block
				if (woas.dom.add_script("plugin", this._mapping(name), js, false)) {
					this._active.push( name );
					return true;
				}
				return false;
			}
		}
		// normal plugins
		if (woas.dom.add_script("plugin", this._mapping(name),
					p, false)) {
			this._active.push( name );
			return true;
		}
		return false;
	},
	
	// remove DOM object for all active plugins
	clear: function() {
		for(var i=0,it=this._active.length;i < it;++i) {
			// remove the DOM object
			this.dom.remove_script("plugin", this._mapping(this._active[i]));
		}
		// reset array
		this._active = [];
		this._all = [];
	},
	
	// map a plugin name to an unique name
	_mapping_cache:[],
	_mapping: function(name) {
		var i = this._mapping_cache.indexOf(name);
		if (i == -1) {
			i = this._mapping_cache.length;
			this._mapping_cache.push(name);
		}
		// return more descriptive names
		if (woas.config.debug_mode)
			return woas._unix_normalize(name).replace("@", '')+"_"+i;
		return i;
	},
	
	load: function() {
		//TODO: get plugins configuration

		// get list of plugins
		var _pfx = "WoaS::Plugins::", l=_pfx.length, name;
		for(var i=0,it=page_titles.length;i < it;++i) {
			if (page_titles[i].substr(0, l) === _pfx) {
				name = page_titles[i].substr(_pfx.length);
				// generate the script element
				this.enable(name);
				this._all.push(name);
			}
		} //efor
	},
	
	list: function() {
		var pt = this._all.length;
		if (pt === 0)
			return "\n\n/No plugins installed/";
		var pg=[];
		for(var i=0;i < pt;++i){
			pg.push("* [[WoaS::Plugins::"+this._all[i]+"|"+this._all[i]+"]]"+
					//TODO: some CSS for the plugin actions
					"&nbsp;&nbsp;[[Javascript::woas.plugins.remove('"+this._all[i]+"')|Delete]]"+
					"&nbsp;&nbsp;[[Javascript::woas._edit_plugin('"+this._all[i]+"')|Edit...]]"+
					"\n");
		}
		return "\n\n"+woas._simple_join_list(pg);
	},
	
	describe_external: function(uris) {
		// show a list of external sources
		var ntext = "<"+"p>This plugin is made up of the following external sources:<"+"/p><"+"ul>", uri;
		for(var i=0;i < uris.length;++i) {
			ntext += "<"+"li>" + "<"+"big>"+(uris[i].is_inline ? "(inline)" : "(external)")+"<"+"/big>&nbsp;";
			ntext += "<"+"a href=\""+uris[i].src+"\" target=\"_blank\">"+uris[i].src+"<"+"/a><"+"/li>\n";
		}
		return ntext+"<"+"/ul>";
	},
	
	// if given page name is a plugin, disable it
	// used when deleting pages
	delete_check: function(pname) {
		var _pfx = "WoaS::Plugins::";
		if (pname.substr(0, _pfx.length) === _pfx)
			this.disable(pname.substr(_pfx.length));
	},

	remove: function(name) {
		var page_name = "WoaS::Plugins::"+name;
		if (!confirm(woas.i18n.CONFIRM_DELETE.sprintf(page_name)))
			return false;
		// first we attempt to disable it, ignoring failure (because it could just not be active)
		this.disable(name);
		woas.delete_page(page_name);
		// remove from array
		var i = this._all.indexOf(name);
		this._all.splice(i,1);
		if (current === "WoaS::Plugins") {
			//HACK: reload plugins
			woas.setHTMLDiv(d$("woas_wiki_area"), woas.parser.parse(woas.get_text("WoaS::Plugins") + this.list()));
		}
		return true;
	}

};

// @module hotkey
woas.hotkey = {
	
	all: {
		"save":		"s",
		"edit":		"e",
		"print":	"p",
		"help":		"h",
		"goto":		"g",
		"cancel":	0x1b,
		"back":		0x8
	},
	cached_default: null,
	custom_accesskeys: [],

	_update_accesskeys: function(new_custom_accesskeys) {
		var ak, a, b, at, bt;
		// we store the length of old access keys before looping because
		// other entries might be added during the cycles
		bt=this.custom_accesskeys.length;
		for(a=0,at=new_custom_accesskeys.length;a < at;++a) {
			found = false;
			for (b=0;b < bt;++b) {
				// access key already exists
				if (this.custom_accesskeys[b].key === new_custom_accesskeys[a].key) {
					found = true;
					break;
				}
			}
			// proceed to addition
			if (!found) {
				ak = document.createElement("a");
				this._hook_fn(ak, new_custom_accesskeys[a].fn);
				ak.accessKey = new_custom_accesskeys[a].key;
				// store the new access key
				this.custom_accesskeys.push({"fn":new_custom_accesskeys[a].fn,"key":new_custom_accesskeys[a].key,
											 "obj":ak});
				d$("woas_custom_accesskeys").appendChild(ak);
			}
		}
		// (3) clear the div content if no custom access key is there (just for safety)
		if (this.custom_accesskeys.length === 0)
			this.setHTML(d$("woas_custom_accesskeys"), "&nbsp;");
	},
	
	_hook_fn: function(obj, fn) {
		woas.log("setting onclick for "+fn);
		if (woas.browser.gecko || woas.browser.webkit)
			obj.setAttribute("onclick", fn+"()");
		else //HACK
			obj.onclick = eval(fn);
	},

	// return the default hotkeys/key bindings
	_cache_default: function() {
		if (this.cached_default === null) {
			this.cached_default="";
			var k;
			for(var hkey in this.all) {
				k = this.all[hkey];
				switch(typeof k) {
					case "string":
					break;
					default: // Number
						k = "0x"+k.toString(16);
				}
				this.cached_default += "$"+hkey.toUpperCase()+"\t"+k+"\n";
			}
		}
		return this.cached_default;
	},

	validate: function(k) {
		// validate hexadecimal hotkey
		if (k.substr(0, 2) == "0x") {
			k = parseInt(k.substr(2), 16);
			if (!k)
				return null;
			return k;
		}
		// validate single ASCII character
		if (k.length>1)
			return null;
		return k;
	},

	load: function(s) {
		var new_custom_accesskeys=[];
		// identify valid alias lines and get the key binding/hotkey
		s.replace(this.reHotkeys, function(str, hkey, lambda, binding) {
			// check that binding is a valid key
			binding = woas.hotkey.validate(binding);
			if (binding === null) {
				woas.log("Skipping invalid key binding for hotkey "+hkey);	//log:1
				return;
			}
			// associate a custom key binding
			if (hkey === "CUSTOM") {
				// store the custom definition for later update
				lambda = lambda.substr(1, lambda.length-2);
				new_custom_accesskeys.push({"fn":lambda, "key":binding});
			} else {
				// convert hotkey to lowercase
				hkey = hkey.toLowerCase();
				// check that hotkey exists
				if (typeof woas.hotkey.all[hkey] == "undefined") {
					woas.log("Skipping unknown hotkey "+hkey);	//log:1
					return;
				}
				// associate hotkey and key binding
				woas.hotkey.all[hkey] = binding;
			}
		});
		// once finished loading hotkey definitions, associate them
		d$("woas_save_hl").accessKey = this.all.save;
		d$("woas_edit_hl").accessKey = this.all.edit;
		d$("woas_print_hl").accessKey = this.all.print;
		d$("woas_help_hl").accessKey = this.all.help;
		// set access key for goto feature
		new_custom_accesskeys.push({fn:"woas.cmd_go_to", key: this.all.goto});
		
		// (1) delete access keys which no more exist
		var found,a,b;
		for(a=0,at=this.custom_accesskeys.length;a < at;++a) {
			found = false;
			for (b=0,bt=new_custom_accesskeys.length;b < bt;++b) {
				if (this.custom_accesskeys[a].key === new_custom_accesskeys[b].key) {
					found = true;
					// access key element was found, update the associated function (if necessary)
					if (this.custom_accesskeys[a].fn !== new_custom_accesskeys[b].fn) {
						this._hook_fn(this.custom_accesskeys[a].obj, new_custom_accesskeys[b].fn);
					}
					break;
				}
			}
			// proceed to removal
			if (!found) {
				d$("woas_custom_accesskeys").removeChild(this.custom_accesskeys[a].obj);
				delete this.custom_accesskeys[a].obj;
				this.custom_accesskeys.splice(a,1);
				--at;
			}
		}
		// (2) add new access keys
		this._update_accesskeys(new_custom_accesskeys);
	},
	
	reHotkeys: /^\$([A-Za-z0-9_]{2,})(\([A-Za-z0-9_]+\))?\s+([\S]+)\s*$/gm
};

// call once during code setup to store the current default hotkeys
woas.hotkey._cache_default();

woas._edit_plugin = function(name) {
	if (go_to("WoaS::Plugins::"+name))
		woas.edit_page(current);
};

var reAliases = /^(\$[A-Za-z0-9_]{2,})\s+(.*?)$/gm;
// match all aliases defined in a page
woas._load_aliases = function(s) {
	this.aliases = [];
	if (s==null || !s.length) return;
	s.replace(reAliases, function(str, alias, value) {
		// save the array with the alias regex and alias value
		var cpok = [ new RegExp(RegExp.escape(alias), "g"), value];
		woas.aliases.push(cpok);
	});
};

woas.aliases = [];

woas.title_unalias = function(aliased_title) {
	// apply aliases on title, from newest to oldest
	for(var i=0,l=this.aliases.length;i < l;++i) {
		aliased_title = aliased_title.replace(this.aliases[i][0], this.aliases[i][1]);
	}
	return aliased_title;
};

woas.macro = {
	// macro definition regex
	reMacroDef: /^(%?[A-Za-z0-9_\.]+)\s*(\(.*?\))?\s*:([\s\S]*)$/,

	// macro syntax plugin code adapted from FBNil's implementation
	parser: function(text){
		// standard macro object
		var macro = { "reprocess": false, "text": text };
		// match macro definition/call
		var M=text.match(this.reMacroDef);
		// if no double colon declaration was found, then do not process anything
		if (M !== null) {
			var fn = M[1];
			// check validity of macro name
			if ((fn.indexOf("..") !== -1) || (fn.charAt(0) === '.') ||
				(fn.charAt(fn.length-1) === '.')) {
					woas.log("Invalid macro name: "+fn);	//log:1
					return macro;
			}
			// check that this is not a macro definition request
			if (fn.charAt(0) === '%') {
				fn = fn.substr(1);
				// when macro is not defined, define it
				if (this.create(fn, M[2], M[3])) {
					// we totally remove the block
					macro.reprocess = false;
					macro.text = "";
		//			macro.text = "<!-- defined "+fn+" macro -->";
				} else { // set some error message
					macro.reprocess = false;
					macro.text = woas._make_preformatted(M[0], "color:red;font-weight:bold");
				}
				return macro;
			}
			var fi = this.names.indexOf(fn);
			if (fi !== -1) {
				macro.text = M[3];
				// if we have no parameters, direct call function
				var pl, rv;
				if (typeof M[2] == "undefined")
					pl = 0;
				else pl = M[2].length;
				try {
					if (pl === 0)
						(this.functions[fi])(macro);
					else {
						// inline insertion of parameters
						// cannot use woas.eval because we need context for 'macro'
						rv = eval( "(woas.macro.functions["+fi+"])"+
									"(macro,"+M[2].substr(1,pl-2)+");"
							);
					}
				}
				catch(e) {
					woas.log("Error during macro execution: "+e);
				}
				// analyze return value
				if (typeof rv == "undefined")
					woas.log("WARNING: "+this.names[fi]+" did not return any value");
				else {
					// when macro returns false we automatically highlight it
					if (!rv) {
						macro.reprocess = false;
						macro.text = woas._make_preformatted(M[0], "color:red;font-weight:bold");
					}
				}
			} else {
				woas.log("Undefined macro "+fn);	//log:1
				macro.text = woas._make_preformatted(macro.text, "color:red");
			}
		}
		return macro;
	},

	// this is the function to be called to register a  macro
	// each macro function must accept a macro object as parameter and modify
	// such object (it is always passed by reference)
	register: function(fn_name, fn_object) {
		if (this.names.indexOf(fn_name) != -1) {
			woas.log("cannot redefine macro "+fn_name); //log:1
			return false;
		}
		this.names.push(fn_name);
		this.functions.push(fn_object);
		return true;
	},

	// some default macros
	default_macros: {
		// advanced transclusion: each newline creates a parameter
		"include" : function(m) {
			var params = m.text.split("\n");
			// embedded transclusion not supported
			if (!params.length || !woas.page_exists(params[0]) || woas.is_embedded(params[0]))
				return false;
			var nt = woas.get_text_special(params[0]);
			if (nt === null)
				return false;
			if (params.length) { // replace transclusion parameters
				nt = nt.replace(/%\d+/g, function(str) {
					var paramno = parseInt(str.substr(1));
					if (paramno < params.length)
						return params[paramno];
					else
						return str;
					} );
			}
			m.text = nt;
			m.reprocess = true;
			return true;
		}
	},

	// the name of macros as they are called from wiki text
	names: [],
	// the actual function objects being called
	functions: [],

	// a reduced charset for javascript argument names
	reFindArgDef: /([a-z0-9_]+)\s*,/gi,
	reFindArgDefLast: /([a-z0-9_]+)\s*$/gi,
	create: function(fn_name, fn_params, fn_code) {
		// duplicated from register function
		if (this.names.indexOf(fn_name) != -1) {
			woas.log("cannot redefine macro "+fn_name); //log:1
			return false;
		}
		// prepare for passing other params
		// parameter definitions can be very limited in charset
		var real_params=[], other_params = "";
		if (((typeof fn_params).toLowerCase() == "string") && fn_params.length) {
			// remove parenthesis
			fn_params = fn_params.substr(1, fn_params.length-2);
			this.reFindArgDef.lastIndex = 0;
			fn_params.replace(this.reFindArgDef, function(str, pname) {
				real_params.push(pname);
			});
			
			this.reFindArgDefLast.lastIndex = this.reFindArgDef.lastIndex;
			fn_params.replace(this.reFindArgDefLast, function(str, pname) {
				real_params.push(pname);
			});
		}

		if (real_params.length)
			other_params = ","+real_params.join(",");
		else other_params = "";
		var obj = woas.eval("function (macro"+other_params+") {\n"+fn_code+"\n}", true);
		if (woas.eval_failed) {
			woas.log("cannot define function "+fn_name+": "+woas.eval_fail_msg); //log:1
			return false;
		}
		return this.register(fn_name, obj);
	},
	
	// code used to save backups of macro definitions
	// called by parser
	_backup: [],
	push_backup: function() {
		this._backup.push(this.names.slice(0));
		this._backup.push(this.functions.slice(0));
	},
	
	pop_backup: function() {
		this.functions = this._backup.pop();
		this.names = this._backup.pop();
	},
	
	has_backup: function() {
		return (this._backup.length !== 0);
	}

}; // end of woas.macro module

// some initialization
woas.macro.names.push("woas.include");
woas.macro.functions.push(woas.macro.default_macros.include);

/*** src/datalayer.js ***/
/*
 *  API for the data layer abstraction
*/

// @module lock
// provides locking facilities by using a file describing locked entries
woas.lock = {
	// hashmap with a lock entry for each active filename
	datasources : {},
	
	_reset : function() {
		// clear object
		this.datasources = {};
		//TODO: add one entry for each expected datasource
	},
	
	_generate_magic_lock : function() {
		return _random_string(10);
	},
	
	_load_locks : function() {
		// locking currently disabled
		return true;
		var lck_file = woas.ROOT_DIRECTORY + woas.config.wsif_ds + ".lock";
		// attempt reading the lock file index
		var lock_data = woas.load_file(lck_file);
		// fail in case of no loading API available
		if (lock_data === null)
			return false;
		var need_save = false;
		// the lock file does not exist, it's time to initialize it
		if (lock_data === false) {
			this._reset();
			// we will write the file
			need_save = true;
		} else {
			// check that
		}
		return true;
	},
	
	_update_locks : function() {
		//TODO: write the lock file index
		return true;
	},
	
	is_locked : function(filename) {
		// if lock is not defined, it is not active of course
		if (typeof this.datasources[filename] == "undefined")
			return false;
		return this.datasources[filename].active;
	},
	
	// called when editing some page which modifies one or more datasources
	// returns true if lock could be held successfully
	hold : function(filename, whom) {
		// locking currently disabled
		return true;
		// (1) each time there is an attempt to lock/unlock something we read the lock file index
		// and check if the datasource has been locked or if there have been changes to some lock
		if (!this._load_locks())
			return false;
		
		// (2) is this file already locked?
		if (this.is_locked(filename)) {
			var lock = this.datasources[filename];
			if (!confirm("%s was locked by %s at %s.\nDo you want to ignore this lock?\n\nWARNING: PRESS OK ONLY IF NOBODY ELSE IS EDITING".
						sprintf(filename, lock.owner, lock.when.toLocaleString()
						)))
				return false;
			// otherwise ignore lock
			lock = null;
		}
		
		// (3) re-create the lock
		this.datasources[filename] = {
			magic : this._generate_magic_lock(),		// magic is used to compare two locks
			owner : whom,								// author of locking
			when : new Date(),							// when locking happened
			active : true
		};
		
		// update the lock index
		return this._update_locks();
	},
	
	release : function(filename) {
		// locking currently disabled
		return true;
		// (1) each time there is an attempt to lock/unlock something we read the lock file index
		// and check if the datasource has been locked or if there have been changes to some lock
		if (!this._load_locks())
			return false;
		// (2) check if datasource is actually locked
		if (typeof this.datasources[filename] == "undefined") {
//			woas.log("BUG: NO LOCK exists for "+filename);	//log:0
			return false;
		}
		// unactive the lock object (but keep it to check if file was modified)
		this.datasources[filename].active = false;
		// update the lock index
		return this._update_locks();
	}
};

woas._wsif_ds_save = function(subpath, plist) {
	// if we have a native sub-path, trigger the WSIF datasource save
	if (subpath.length === 0)
		return;
	// always save in the root directory
	// code disabled since we always save the full backup
//	if (typeof plist != "undefined" )
//		done = this._native_wsif_save(path,	subpath, true, true, "", true, plist); else
	this._native_wsif_save(woas.ROOT_DIRECTORY, subpath, this.config.wsif_ds_lock,
							!this.config.wsif_ds_multi,	!this.config.wsif_ds_multi,
							this.config.wsif_author, true);
};

//API1.0: save all pages
woas.full_commit = function() {
	this._wsif_ds_save(this.config.wsif_ds, this.config.wsif_ds_lock);
	return this._save_to_file(true);
};

//API1.0: save WoaS configuration
woas.cfg_commit = function() {
	if (this.config.wsif_ds.length !== this._old_wsif_ds_len)
		this._wsif_ds_save(this.config.wsif_ds, this.config.wsif_ds_lock);
	return this._save_to_file(false);
};

//API1.0: save specific list of pages
// plist is a list of page indexes which need to be saved
woas.commit = function(plist) {
	this._wsif_ds_save(this.config.wsif_ds, this.config.wsif_ds_lock, plist);
	// performs full save, while the single page + global header could be saved instead
	return this._save_to_file(true);
};

//API1.0: delete specific list of pages
// plist is a list of page indexes which need to be saved (not allowed to be empty)
woas.commit_delete = function(plist) {
	// update only the native WSIF index (leaves back deleted pages)
	this._wsif_ds_save(this.config.wsif_ds, this.config.wsif_ds_lock, []);
	// performs full save, while the single page + global header could be saved instead
	return this._save_to_file(true);
};

//API1.0: event called after some page is being saved
// plist can be undefined if all pages were saved
woas.after_pages_saved = function(plist) {
	// we assume that everything was saved
	if (typeof plist == "undefined") {
		this.save_queue = [];
		return;
	}
	// we remove each of the saved pages from queue (needs TESTING!)
	for(var i=0,l=plist.length;i<l;i++) {
		var p = this.save_queue.indexOf(plist[i]);
		if (p !== -1)
			this.save_queue.splice(p,1);
	}
};

//API1.0: event called when the config was successfully saved
woas.after_config_saved = function() {
	woas.cfg_changed = false;
};

/*** src/i18n.js ***/

// internationalization language resources
woas.i18n = {
	ACCESS_DENIED: "Access denied to page '%s'",
	ALT_BROWSER_INPUT: "Please specify full path to file '%s' because your browser does not allow such path to be read directly for security reasons.",
	ASK_MENU_LINK: "Do you want to add a link into the main menu?",
	B64_REQ: " (requires %s due to base64 encoding)",
	CANCEL_EDITING:"Changes to this page will not be saved.",
	CONFIRM_OVERWRITE: "Page \"%s\" already exists. Overwrite it?",
	CONFIRM_DELETE:"Are you sure you want to DELETE page '%s'?",
	CONFIRM_DELETE_ALL1: "Are you going to ERASE all your pages?",
	CONFIRM_DELETE_ALL2: "This is the last confirm needed in order to ERASE all your pages.\n\nALL YOUR PAGES WILL BE LOST\n\nAre you sure you want to continue?",
	CONFIRM_DELETE_FILE: "Are you sure you want to delete this file?",
	CONFIRM_DELETE_IMAGE: "Are you sure you want to delete image '%s'?",
	CONFIRM_EXPORT: "Do you want to export %s in the below specified path?",
	CONFIRM_LOCK: "Do you want to use the last password entered to lock this page '%s'?",
	CONFIRM_LOCK_LAST: "The password was last time used on page: %s",
	CONFIRM_READ_ONLY: "Are you sure you want to set this WoaS as read-only? You will have to manually edit the file to revert this change.",
	CONFIRM_REMOVE_ENCRYPT: "Do you want to remove encryption for page '%s'?",
	DELETE:"Delete page:",
 	DELETE_FILE:"Delete embedded file",
 	DELETE_IMAGE:"Delete embedded image",
	DELETE_PAGE_PROMPT: "Delete page:",
	DISPLAY_FULL_FILE: "Display full file",
	DUP_NS_ERROR: "Cannot duplicate into File:: or Image:: namespace!",
	EDITING:"Editing %s",
	EMPTY_TITLE: "Pages with empty title are not allowed",
	ERR_MARKER: "%s marker not found!",
	ERR_NO_PWD: "No password set for decryption of page '%s'\nPlease click the key icon and enter a password",
	ERR_PAGE_NS: "You cannot create a page as a namespace",
	ERR_RESERVED_NS: "Namespace '%s' is reserved",
	ERR_SEL_FILE: "A file must be selected",
	ERR_VAR_MARKER: "Marker variable not found!",
 	EXPORT_FILE:"Export file",
 	EXPORT_IMAGE:"Export image",
	EXPORT_OK: "%d/%d pages exported successfully",
	FAILED_ERASE:"Saving the erased WoaS has failed, please reload it otherwise you will be working with unconsistent data",
	FILE_DISPLAY_LIMIT: "Only the first 1024 bytes are displayed",
	FILE_SELECT_ERR: "A file must be selected",
	FILE_SIZE: "File size",
	HEIGHT: "Height",
	IMPORT_INCOMPAT: "Incompatible version: %s",
	IMPORT_OLD_VER: "If this is a WoaS older than v0.9.6B, you should import it with WoaS 0.11.x",
	IMPORT_OK: "%s pages imported successfully (%d pages skipped)",
	IMPORT_UNRECON: "Unrecognized format",
	INSERT_NEW:"Insert new page title",
	INVALID_ALIAS: "Invalid alias '%s', ignoring it",
	INVALID_DATA:"Invalid collected data!",
	INVALID_SPECIAL: "Invalid special page.",
	INVALID_TITLE: "Title cannot contain ':::' and any of these characters:\n< > | [ ] { }",
	LAST_MODIFIED: "Last Modified: ",
	LOADING: "Loading Wiki on a Stick...",
	LOAD_ERR: "Cannot load specified file",
	MIME_TYPE: "Mime type",
	NO_ERROR: "No error",
	NO_JAVA:"It was not possible to use TiddlySaver java applet nor direct Java saving.",
	NO_TIDDLY_SAVER:"The TiddlySaver java applet was not available.",
	PAGE_EXISTS: "A page with title '%s' already exists!",
	PAGE_NOT_EXISTS: "Page does not exist: ",
	PAGE_NOT_FOUND: "Page not found. Do you want to create it?",
	PRINT_MODE_WARN: "Sorry, you cannot browse the wiki while in print mode",
	PWD_QUERY: "Please enter a password",
	READ_ONLY: "This Wiki on a Stick is read-only",
	SAVE_ERROR:"Unable to save file '%s'.",
	SERVER_MODE: "You are using Wiki on a Stick on a webserver; your changes cannot be saved neither through the webserver or locally.\n\n"+
					"The correct usage of Wiki on a Stick is local, so you should use a local copy of this page to exploit the save features.\n"+
					"All changes made to this copy of Wiki on a Stick will be lost.",
	STATIC_NOT_FOUND: "Static page '%s' not found!",
	TIDDLY_HELP:"Please check that TiddlySaver.jar is in the same directory of this WoaS and that you have enabled Java permissions for it",
	TOO_LONG_TITLE: "Maximum title length is %d characters",
	UNSPECIFIED_JAVA_ERROR: "Please check the Java console for errors regarding last operation and check that it's not due to your browser/java restrictions",
	UNSUPPORTED_BROWSER: "Your browser might not be supported, please report a bug with your UserAgent string:\n%s",
	WIDTH: "Width",
	WRITE_PROTECTED: "Sorry, this Wiki on a Stick is already write-protected",
	WSIF_BAD_HV: "Could not locate end of header value",
	WSIF_NO_HN: "Could not locate header name",
	WSIF_NO_VER: "Could not read WSIF version",
	WSIF_NS_VER: "WSIF version %s not supported!",
	CANNOT_LOCK_RESERVED: "Cannot lock a page in a reserved namespace",
	CONTINUE_WAIT_LOAD: "The loading process seems stuck.\nPlease click OK to keep waiting or Cancel to break.",
	MODE_NOT_AVAIL: "File mode 0x%s is not available on this browser"
};

// do not use any copyrighted wordlist here
woas.i18n.common_words = ['the','of','to' ,'and' ,'a' ,'in' ,'is' ,'it' ,'you' ,'that' ,'he' ,'was' ,'for','on' ,'are' ,'with' ,'as' ,'I' ,'his' ,'they' ,'be' ,'at' ,'one' ,'have' ,'this' ,'from' ,'or' ,'had' ,'by' , 'an', 'all' ];

/*** src/import.js ***/
// @module importer

/* NOTES ABOUT PREVIOUS VERSIONS
		0.12.0:
			* introduced some config options: new_tables_syntax, store_mts, folding_style
			* introduced plugins (which deprecate WoaS::Bootscript)
			* dropping support for all WoaS before 0.9.6B
		0.11.7:
			* 'nav_history' config option replaces 'open_last_page'
		0.11.2:
			* introduced parsing mechanism which does not mess with var declarations inside JavaScript strings
			* introduced WoaS::Hotkeys, WoaS::CSS::Core, WoaS::CSS::Custom
			* introduced woas.config.safe_mode option
			* introduced woas.config.wsif_ds* options
		0.10.7:
			* introduced WoaS::Plugins and changed WoaS::Bootscript page type from embedded to normal
		0.10.0:
			* introduced page_mts for global page modified timestamp
		0.9.7:
			* introduced WoaS::Aliases
*/

woas.importer = {
//public:
	pages_imported: 0,
	total: 0,

//private:
	// property names used to retrieve default values from stored bitmask
	_settings_props: ["i_comment_js", "i_comment_macros", "i_woas_ns",
	// the last 3 options are ignored for WSIF import
					"i_config", "i_styles", "i_content"],
	// the overwrite option covers bits 6,7
	_OVR_ID: 6,
	// options
	i_config: true,					// import configuration (XHTML only)
	i_styles: false,				// import stylesheet (XHTML only)
	i_content: true,				// import content pages (XHTML only)
	i_comment_js: true,				// disable 'script' tags
	i_comment_macros: true,			// disable macro blocks '<<<...>>>'
	i_woas_ns: true,				// import pages from WoaS:: namespace
	i_overwrite: 1,					// overwrite mode (0 - erase, 1 - ignore, 2 - overwrite, 3 - ask)

	// used internally
	new_main_page: null,
	current_mts: null,
	pages: [],			// imported page objects array
	_reference: [],		// linear array containing page id or null, used privately by _get_import_vars()
	
	// runtime dynamic update variables
	_plugins_update: [],
	_plugins_add: [],
	_update_css: false,
	_update_hotkeys: false,
	_update_aliases: false,
	_bootscript_code: "",

	_fix_mts_val: function(mts, old_version) {
		// we did not have a timestamp before 0.10.0
		if (old_version < 100)
			return this.current_mts;
		// will catch the 'undefined' ones also
		if (!mts)
			return 0;
		// fixup the mts value in some old buggy version
		if ((old_version===100) || (old_version===101)) {
			// ignore the old null value
			if (mts === 0x4b61cbad)
				mts = 0;
		}
		return mts;
	},
	
	_filter_by_title: function(title) {
		// we are not using is_reserved() because will be inconsistant in case of enabled edit_override
		// check pages in WoaS:: namespace
		if (title.substr(0,6) === "WoaS::") {
			// can we import from WoaS namespace?
			if (!woas.importer.i_woas_ns)
				return false;
			// never overwrite help pages with old ones
			if (title.indexOf("WoaS::Help::") === 0)
				return false;
			// skip other core WoaS:: pages
			if (woas.static_pages2.indexOf(title) !== -1)
				return false;
			if (title === "WoaS::Custom::CSS")
				// custom CSS is allowed only when importing CSS
				return woas.importer.i_styles;
			
			// here we allow Plugins, Aliases, Hotkeys
			
			return true;
		} else if (title.substr(0, 9) === "Special::") {
			// always skip special pages and consider them system pages

			return false;
		}
		
		// if not on bad list, it's OK
		return true;
	},

	// function used to collect variables
	_get_import_vars: function(data, ignore_array, old_version) {
		var jstrings=[], fail = false;
		// (1) take away all javascript strings (most notably: content and titles)
		// WARNING: quoting hacks lie here!
		data = data.replace(/\\'/g, ":-"+woas.parser.marker).replace(this.reJString, function (str) {
			// restore quotes
			jstrings.push(str.substr(1, str.length-2).replace(woas.importer.reRequote, "\\'"));
			return woas.parser.marker+":"+(jstrings.length-1).toString();
		});
		// (2) rename the variables
		data.replace(/([^\\])\nvar\s+(\w+)\s*=\s*([^;]+);/g, function (str, $1, var_name, definition) {
			if (fail) return;
			// it must not be in array
			if (ignore_array.indexOf(var_name) !== -1)
				return;
			if (
					// main_page was not in config object for 0.10.8 and below
					(old_version <= 108) && (var_name === "main_page") ) {
				woas.importer.new_main_page = woas.eval(definition.replace(woas.importer.reJStringRep,
								function (str, id) { return "'"+jstrings[id]+"'";}
							), true);
				return;
			}
			// the rest of variables are for content, so exit if we don't want content
			if (!woas.importer.i_content)
				return;
			// save evaluation if we don't want last modified timestamp
			if (!woas.config.store_mts && (var_name === "page_mts"))
				return;
			
			// evaluate the real array
			var the_var = woas.eval(definition.replace(woas.importer.reJStringRep,
								function (str, id) { return "'"+jstrings[id]+"'";}
							), true);

			// OK, we want this variable, evaluate it
			switch (var_name) {
				case "page_titles":
					// titles come before other properties, so we create all objects now
					for(var i=0,it=the_var.length;i < it;++i) {
						// call the title filtering hook
						if (woas.importer._filter_by_title(the_var[i])) {
							woas.importer.pages.push( { title: the_var[i], attrs: 0,
												mts: (old_version > 97) ? 0 : (woas.config.store_mts ? woas.importer.current_mts : 0),
												body: null } );
							// add object by-ref
							woas.importer._reference.push( woas.importer.pages[woas.importer.pages.length-1] );
						} else // no page reference
							woas.importer._reference.push( null );
					}
				break;
				case "page_attrs":
					// consistency check
					if (the_var.length !== woas.importer._reference.length) {
						woas.log("ERROR: page attributes array is not consistent ("+the_var.length+" != "+woas.importer._reference.length+")");
						fail = true;
						break;
					}
					for(var i=0,it=the_var.length;i < it;++i) {
						// skip filtered pages
						if (woas.importer._reference[i] === null)
							continue;
						woas.importer._reference[i].attrs = the_var[i];
					}
				break;
				case "page_mts": // available only on 0.10.0 and above
					// consistency check
					if (the_var.length !== woas.importer._reference.length) {
						woas.log("WARNING: page timestamps array is not consistent ("+the_var.length+" != "+woas.importer._reference.length+")");
						break;
					}
					for(var i=0,it=the_var.length;i < it;++i) {
						// skip filtered pages
						if (woas.importer._reference[i] === null)
							continue;
						woas.importer._reference[i].mts = woas.importer._fix_mts_val(the_var[i], old_version);
					}
				break;
				case "pages":
					// consistency check
					if (the_var.length !== woas.importer._reference.length) {
						woas.log("ERROR: page bodies array is not consistent ("+the_var.length+" != "+woas.importer._reference.length+")");
						fail = true;
						break;
					}
					for(var i=0,it=the_var.length;i < it;++i) {
						// skip filtered pages
						if (woas.importer._reference[i] === null)
							continue;
						woas.importer._reference[i].body = the_var[i];
					}
				break;
				// silently ignore these
				case "backstack": case "current": break;
				default:
					woas.log("Ignoring unexpected variable "+var_name);
			} // switch
				
		});
		// finished importing variables, clear references array
		this._reference = [];
		// clear partial results on failure
		if (fail)
			this.pages = [];
		woas.log("get_import_vars() scanned "+this.pages.length+" page definitions");
	},

	// apply options i.e. javascript security settings
	_hotfix_on_import: function(NP) {
		// exit if no replace is needed
		if (!this.i_comment_js && !this.i_comment_macros)
			return;
		// only plain wiki and locked pages can be hotfixed
		if (NP.attrs > 1)
			return;
		// comment out all javascript blocks
		var snippets = [];
		// put away XHTML comments and nowiki blocks
		NP.body = NP.body.replace(reComments, function (str, $1, dynamic_nl) {
				var r = woas.parser.place_holder(snippets.length, "", dynamic_nl);
				snippets.push(str);
				return r;
		}).replace(reNowiki, function (str, $1, dynamic_nl) {
				var r = woas.parser.place_holder(snippets.length, "", dynamic_nl);
				snippets.push(str);
				return r;
		});
		if (this.i_comment_js)
			NP.body = NP.body.replace(reScripts, "<"+"disabled_script$1>$2<"+"/disabled_script>$3");
		if (this.i_comment_macros)
			NP.body = NP.body.replace(reMacros, "<<< Macro disabled\n$1>>>$2");
		// clear dynamic newlines
		NP.body = NP.body.replace(woas.parser.reNL_MARKER, "");
		// restore everything
		woas.parser.undry(NP, snippets);
	},
	
	// add directly without checking for duplicates
	//NOTE: will not set 'pi' property
	_inject_import_hook: function(page) {
		page_titles.push(page.title);
		pages.push(page.body);
		page_attrs.push( page.attrs );
		// during import timestamp is already fixed when originally reading the variable
		page_mts.push(page.mts);
		// set self reference
		page.i = pages.length-1;
		return true;
	},
	
	_core_import_hook: function(page) {
//		woas.log("Importing page "+page.title);	//log:0
		var pi = woas.page_index(page.title);
		if (pi === -1) { // new page title
			woas.importer._inject_import_hook(page);
			page.pi = -1;
		} else { // page already existing, overwriting
			if (woas.importer.i_overwrite === 1) {
				// ignore already-existing pages
				return false;
			} else if (woas.importer.i_overwrite === 3) {
				if (!confirm(woas.i18n.CONFIRM_OVERWRITE.sprintf(page.title)))
					return false;
			}
			page_titles[pi] = page.title;
			pages[pi] = page.body;
			page_attrs[pi] = page.attrs;
			page_mts[pi] = page.mts;
			page.i = page.pi = pi;
		}
		return true;
	},
	
	// normal import hook - shared for XHTML and WSIF import
	_import_hook: function(page) {
		var that = woas.importer;
		that._hotfix_on_import(page);

		that._core_import_hook(page);

		// take note of plugin pages and other special runtime stuff
		var _pfx = "WoaS::Plugins::";
		if (page.title.substr(0, _pfx.length) === _pfx) {
			// does plugin already exist?
			if (page.pi !== -1)
				that._plugins_update.push(page.title.substr(_pfx.length));
			else
				that._plugins_add.push(page.title.substr(_pfx.length));
		} else if (page.title === "WoaS::Aliases")
			// check if we need to update aliases and hotkeys
			that._update_aliases = true;
		else if (page.title === "WoaS::Hotkeys")
			that._update_hotkeys = true;
		else if (page.title === "WoaS::CSS::Custom")
			that._update_css = true;
		
		return true;
	},
	
	_clear: function() {
//		this.pages = [];
		this._update_css = false;
		this._update_aliases = false;
		this._update_hotkeys = false;
		this._plugins_add = [];
		this._plugins_update = [];
	},
	
	_old_version: null,
	_upgrade_content: function (P) {
		var that = woas.importer;
		// fix the old bootscript page
		if (that._old_version < 120) {
			if (P.title === "WoaS::Bootscript") {
				// convert old base64 bootscript to plain text
				if (that._old_version < 107)
					that._bootscript_code = woas.base64.decode(P.body);
				else
					that._bootscript_code = P.body;
				that.pages_imported++;
				woas.progress_status(that.pages_imported/that.pages.length);
				return false;
			}
		} // since 0.12.0 we no more have a bootscript page

		// check that imported image is valid
		if (P.attrs & 8) {
			// the image is not valid as-is, attempt to fix it
			if (!that.reValidImage.test(P.body)) {
				// do not continue with newer versions or if not base64-encoded
				if ((that._old_version>=117) || !woas.base64.reValid.test(P.body)) {
					woas.log("Skipping invalid image "+P.title);
					return false;
				}
				// we assume that image is double-encoded
				P.body = woas.base64.decode(P.body);
				// check again for validity
				if (!that.reValidImage.test(P.body)) {
					woas.log("WARNING: skipping invalid image "+P.title); //log:1
					return false;
				}
				woas.log("Fixed double-encoded image "+P.title); //log:1
			}
			// try to fix the 'undefined' mime type bug
			if (that._old_version < 120) {
				if (that.reImageBadMime.test(P.body))
					// attempt to find the correct mime
					P.body = "data:"+woas._guess_mime(P.title)+P.body.substr(14);
			}
		} // check images

		// fix the trailing nul bytes bug in encrypted pages
		// extended from 0.10.4 to 0.12.0 because was not fixed on new pages
		if ((that._old_version>=102) && (that._old_version<120)
			&& (P.attrs & 2)) {
			var rest = P.body.length % 16;
			if (rest) {
				woas.log("removing "+rest+" trailing bytes from page "+P.title); //log:1
				while (rest-- > 0) {P.body.pop();}
			}
		}
			
		// proceed to actual import
		if (that._import_hook(P)) {
			++that.pages_imported;
			woas.progress_status(that.pages_imported/that.pages.length);
		}
		return true;
	},
	
	_import_content: function(old_version) {
		this._old_version = old_version;
		for (var i=0; i < this.pages.length; i++) {
			this._upgrade_content(this.pages[i]);
		}
	},
	
	do_import: function(ct) {
		// initialize
		this.pages_imported = 0;
		this.total = 0;

		var fail=false;
		
		do { // a fake do...while to ease failure return
		
		// get WoaS version
		var old_version,
			ver_str = ct.match(/var woas = \{"version":\s+"([^"]+)"\s*\};(\r\n|\n)/);
		if (!ver_str || !ver_str.length) {
			woas.alert("Could not determine WoaS version\n"+woas.i18n.IMPORT_OLD_VER);
			fail = true;
			break;
		}
		ver_str = ver_str[1];
		woas.log("Imported file version string: "+ver_str);	// log:1
		switch (ver_str) {
			case "0.9.6B":
			case "0.9.7B": // never released officially
				ver_str = ver_str.substr(0, ver_str.length-2);
			case "0.10.0": case "0.10.1":
			case "0.10.2": case "0.10.3":
			case "0.10.4": case "0.10.5":
			case "0.10.6": case "0.10.7":
			case "0.10.8": case "0.10.9":
			case "0.11.0": case "0.11.1":
			case "0.11.2": case "0.11.3":
			case "0.11.4": case "0.11.5":
			case "0.11.6": case "0.11.7":
			case "0.11.8": case "0.11.9":
			case "0.12.0":
			old_version = Number(ver_str.substr(2).replace(/\./g, ""));
				break;
			default:
				woas.alert(woas.i18n.IMPORT_INCOMPAT.sprintf(ver_str)+woas.i18n.IMPORT_OLD_VER);
				fail=true;
		}
		if (fail) break;

		// import the variables
		var	imported_css = null,
			// used during import from older versions
			old_cfg;
		if (this.i_config)
			old_cfg = d$.clone(woas.config);
			
		this.new_main_page = woas.config.main_page;

		// locate the random marker
		var old_marker = ct.match(/\nvar __marker = "([A-Za-z\-\d]+)";(\r\n|\n)/);
		if (!old_marker) {
			woas.alert(woas.i18n.ERR_MARKER);
			fail = true;
		}
		if (fail) break;
		old_marker = old_marker[1];

		// import the CSS head tag in versions before 0.11.2
		if (this.i_styles && (old_version < 112)) {
			ct.replace(this.reOldStyleBlock, function (str, $1) {
				imported_css = $1;
			});
		} // 0.11.2+, we'll manage CSS import at the page level

		var data = woas._extract_src_data(old_marker, ct, true, this.new_main_page, true);
		// some GC help: we no more need the big content variable
		ct = null;		
		
		if (this.i_config) {
			var cfgStartMarker = 'woas["'+'config"] = {',
				// grab the woas config definition
				cfg_start = data.indexOf(cfgStartMarker),
				cfg_found = false;
			
			if (cfg_start !== -1) {
				var cfg_end = data.indexOf('}', cfg_start+cfgStartMarker.length);
				if (cfg_end !== -1) {
					woas.config = woas.eval(data.substring(cfg_start+cfgStartMarker.length-1, cfg_end+1), true);
					cfg_found = !woas.eval_failed;
				}
			}
						
			if (!cfg_found) {
				woas.log("Failed to import old configuration object");
			} else {
				// add the new debug option
				if (old_version<=107)
					woas.config.debug_mode = old_cfg.debug_mode;
				// add the new safe mode
				if (old_version < 112) {
					woas.config.safe_mode = old_cfg.safe_mode;
					//NOTE: WSIF datasource options are not imported at all
				}
				// renamed one config option
				if (old_version < 117) {
					woas.config.nav_history = woas.config.open_last_page;
					delete woas.config.open_last_page;
				}
				// introduced new options
				if (old_version < 120) {
					woas.config.new_tables_syntax = old_cfg.new_tables_syntax;
					woas.config.store_mts = old_cfg.store_mts;
					woas.config.folding_style = old_cfg.folding_style;
					woas.config.import_settings = old_cfg.import_settings;
				}
				// check for any undefined config property - for safety
				for(p in woas.config) {
					// remove things from the past
					if (typeof old_cfg[p] == "undefined") {
						woas.log("BUG: removing invalid config option '"+p+"'");
						delete woas.config[p];
						continue;
					}
					if ((typeof woas.config[p] == "undefined") && (typeof old_cfg[p] != "undefined"))
						woas.config[p] = old_cfg[p];
				}
				
				// put back the old values for WSIF datasource
				woas.config.wsif_author = old_cfg.wsif_author;
				woas.config.wsif_ds = old_cfg.wsif_ds;
				woas.config.wsif_ds_lock = old_cfg.wsif_ds_lock;
				woas.config.wsif_ds_multi = old_cfg.wsif_ds_multi;
				
			} // done importing config object
		} // i_config

		// modified timestamp for pages before 0.10.0
		this.current_mts = Math.round(new Date().getTime()/1000);
		
		// import the pages data
		this._get_import_vars(data, ['woas', '__marker', 'version', '__config'],
							old_version);
		// some GC help
		data = null;
		
		// apply upgrade fixes
		if (this.i_content) {
			this._import_content(old_version);
			this.total = this.pages.length;
			// GC cleanup
			this.pages = [];
		}
		
		// eventually add the new missing page
		if (old_version <= 112) {
			// take care of custom CSS (if any)
			if (imported_css !== null) {
				// import it as a page
				this._import_hook( {
					title: "WoaS::CSS::Custom",
					attrs: 0,
					mts: woas.config.store_mts ? this.current_mts : 0,
					body: imported_css
				} );
			}
		}
		// set the new config variable
		if (this.i_config) {
			if (old_version<=108)
				woas.config.main_page = old_cfg.main_page;
			// apply the new main page if that page exists
			if ((this.new_main_page !== old_cfg.main_page) && woas.page_exists(this.new_main_page))
				woas.config.main_page = this.new_main_page;
		}
		
		} while (false); // fake do..while ends here
		
		// fix configuration for older versions
		if (old_version < 114) {
			if (!woas.config.nav_history) {
				// reset some variables which were not reset in those older versions
				backstack = [];
				current = woas.config.main_page;
			}
		}

		// if there is bootscript code, create a new plugin for it
		// skip empty bootscripts and also default bootscript
		var trimmed_bs = woas.trim(this._bootscript_code);
		if ((trimmed_bs.length !== 0) && (trimmed_bs !== '/* insert here your boot script */')
			&& (trimmed_bs !== '// Put here your boot javascript')) {
			var chosen_name = "WoaS::Plugins::Bootscript", base_name = chosen_name, i=0;
			while (page_titles.indexOf(chosen_name) !== -1) {
				chosen_name = base_name + "_" + (i++).toString();
			}
			woas.log("Old bootscript code will be imported as "+chosen_name);
			// now create such plugin by directly importing it
			this._import_hook( {
				title: chosen_name,
				body: "/* This JavaScript code was automatically imported by WoaS from your former WoaS::Bootscript */\n"+this._bootscript_code,
				attrs: 0,
				mts: woas.config.store_mts ? this.current_mts : 0
			} );
		}
		
		// always update run-time stuff, even on failure
		this._after_import();
		
		// clear everything else
		this._clear();

		// return false on failure
		return !fail;
	},
	
	_after_import: function() {
		var that = woas.importer;
		// refresh in case of CSS, aliases and/or hotkeys modified
		if (that._update_css)
			woas.css.set(woas.get_text("WoaS::CSS::Core")+"\n"+woas.get_text("WoaS::CSS::Custom"));
		if (that._update_aliases)
			woas._load_aliases(woas.get_text("WoaS::Aliases"));
		if (that._update_hotkeys)
			woas.hotkey.load(woas.get_text("WoaS::Hotkeys"));
		
		// add/update plugins
		for(var i=0,it=that._plugins_update.length;i < it;++i) {
			woas.plugins.update(that._plugins_update[i]);
		}
		for(var i=0,it=that._plugins_add.length;i < it;++i) {
			// plugin should be on the list
			woas.plugins._all.push(that._plugins_add[i]);
			woas.plugins.enable(that._plugins_add[i]);
		}
		
	},

	// regular expressions used to not mess with title/content strings
	reRequote: new RegExp(":-"+woas.parser.marker, "g"),
	reJString: new RegExp("'[^']*'", "g"),
	reJStringRep: new RegExp(woas.parser.marker+":"+"(\\d+)", "g"),
	reValidImage: /^data:\s*[^;]*;\s*base64,\s*/,
	reImageBadMime: /^data:undefined;\s*base64,\s*/,
	reOldStyleBlock: new RegExp("<"+"style\\s.*?type=\"?text\\/css\"?[^>]*>((\\n|.)*?)<"+"\\/style>", "i")

};

// called from Special::Import - import WoaS from XHTML file
woas.import_wiki = function() {
	if (!woas._import_pre_up(true))
		return false;

	// set hourglass
	this.progress_init("Import WoaS");

	// file will be loaded as ASCII to overcome browsers' limitations
	var ct = this.load_file(null, this.file_mode.ASCII_TEXT);
	if (ct === null) {
		// remove hourglass
		this.progress_finish();
		return false;
	}
	if (ct === false) {
		this.alert(this.i18n.LOAD_ERR);
		// remove hourglass
		this.progress_finish();
		return false;
	}

	var rv = this.importer.do_import(ct);
	
	// remove hourglass
	this.progress_finish();
	
	if (rv) {
		// inform about the imported pages / total pages present in file
		this.alert(this.i18n.IMPORT_OK.sprintf(this.importer.pages_imported+"/"+this.importer.total,
												this.importer.total - this.importer.pages_imported));
		
		// move to main page
		current = this.config.main_page;
	}
	
	// always save if we have erased the wiki
	if ((this.importer.i_overwrite === 0) || rv)
		this.full_commit();

	if (rv) {
		this.refresh_menu_area();
		this.set_current(this.config.main_page, true);
	}
	
	// supposedly, everything went OK
	return rv;
};

woas._file_ext = function(fn) {
	var m=fn.match(/\.(\w+)$/);
	if (m === null) return "";
	return "."+m[1];
};

woas._import_pre_up = function(all_options) {
	// check if this WoaS is read-only
	if (!this.config.permit_edits) {
		this.alert(woas.i18n.READ_ONLY);
		return false;
	}
	// grab the common options
	this.importer.i_comment_js = d$.checked("woas_cb_import_comment_js");
	this.importer.i_comment_macros = d$.checked("woas_cb_import_comment_macros");
	this.importer.i_woas_ns = d$.checked("woas_cb_import_woas_ns");
	//NOTE: i_overwrite is automatically set when clicking
	if (all_options) {
		// grab the XHTML-only options
		this.importer.i_styles = d$.checked('woas_cb_import_styles');
		this.importer.i_config = d$.checked('woas_cb_import_config');
		this.importer.i_content = d$.checked('woas_cb_import_content');
	} else {
		// these options are not available for WSIF
		this.importer.i_styles = this.importer.i_content = true;
	}
	
	var old_is = woas.config.import_settings;
	// now store these values
	woas.config.import_settings = this.bitfield.get_object(this.importer, this.importer._settings_props);
	// set also bits for overwrite options
	woas.config.import_settings = this.bitfield.set(this.config.import_settings, this.importer._OVR_ID,
									this.importer.i_overwrite & 1, this.config.import_settings);
	woas.config.import_settings = this.bitfield.set(this.config.import_settings, this.importer._OVR_ID+1,
									this.importer.i_overwrite & 2, this.config.import_settings);
	// check if configuration changed
	this.cfg_changed |= (woas.config.import_settings !== old_is);
	// check if user wants total erase before going on
	if (this.importer.i_overwrite === 0) {
		if (!this.erase_wiki())
			return false;
	}
	
	return true;
};

// called from Special::ImportWSIF
woas.import_wiki_wsif = function() {
	if (!woas._import_pre_up(false))
		return false;
	
	// automatically retrieve the filename (will call load_file())
	var done = woas._native_wsif_load(null, false /* no locking */, false /* not native */, 0,
			this.importer._upgrade_content, this.importer._filter_by_title,
			this.importer._after_import);
	if (done === false && (woas.wsif.emsg !== null))
		this.crash(woas.wsif.emsg);

	if (done !== false) {
		// add some info about total pages
		var skipped;
		if (this.wsif.expected_pages !== null) {
			skipped = this.wsif.expected_pages-done;
			done = String(done)+"/"+woas.wsif.expected_pages;
		} else skipped = 0;
		this.alert(woas.i18n.IMPORT_OK.sprintf(done, skipped));
		this.refresh_menu_area();
		// now proceed to actual saving
		this.commit(woas.wsif.imported);
	} else {
		// always save if we have erased the wiki
		if (this.importer.i_overwrite === 0)
			this.full_commit();
	}

	return done;
};

/*** src/export.js ***/
// WoaS 'exporter' module
woas.exporter = {
	_unix_norm: false,
	_default_ext: 'html',

	// arrays/objects using during export
	_title2fn: {},
	_further_pages: [],
	_export_fnames_array: [],
	_settings: {},
	
	clear: function() {
		this._export_fnames_array = [];
		this._title2fn = {};
		this._further_pages = [];
		this._settings = {};
	},
	
	// export wiki in XHTML/CSS and attachment files
	do_export: function () {
		this._settings.custom_scripts = "";
		var data;
		if (this._settings.js_mode==2) {
			//export all active plugins as javascript code
			var js_fn;
			for(var pi=0,pt=woas.plugins._active.length;pi<pt;++pi) {
				data = woas.plugins.get(woas.plugins._active[pi]);
				if (woas.plugins.is_external) {
					// data is an array of sources, go through it
					for(var i=0;i<data.length;++i) {
						this._settings.custom_scripts += '<'+'sc'+'ript type="text/javascript" src="'+data[i]+'"><'+"/script>\n";
					}
				} else {
					js_fn = woas._unix_normalize(woas.plugins._active[pi])+".js";
					if (woas.save_file(this._settings.xhtml_path+js_fn,
										woas.file_mode.ASCII, data)) {
						this._settings.custom_scripts += '<'+'script type="text/javascript" src="'+js_fn+'"><'+"/script>\n";
					}
				}
			}
		}

		var l = page_titles.length, fname = "", done = 0, total = 0, mnupos;
		data = null;
		for (var pi=0;pi < l;pi++) {
			// do skip physical special pages
			if (page_titles[pi].match(/^Special::/)) continue;
			if (woas.static_pages2.indexOf(page_titles[pi]) !== -1) continue;
			// skip also the unexportable WoaS pages
			if (woas.unexportable_pages2.indexOf(page_titles[pi]) !== -1) continue;
			// do skip menu pages (they are already included in each page)
			mnupos = page_titles[pi].indexOf("::Menu");
			if ((mnupos !== -1) &&
				(mnupos === page_titles[pi].length-6)) continue;
			data = woas.get_text_special(page_titles[pi]);
			// skip pages which could not be decrypted
			if (data === null) continue;
			fname = this._get_fname(page_titles[pi], true);
			// will skip WoaS::Plugins::* and WoaS::Aliases
			if (fname === '#') {
	//			log("skipping "+page_titles[pi]);
				continue;
			}
			++total;
			if (woas.is__embedded(pi)) {
				if (woas.is__image(pi)) {
					if (!woas._b64_export(data, this._settings.img_path+fname))
						break;
					// image export was successful, continue to next page
					else { ++done; continue; }
				} else {
					// fully export the file
					if (!woas._b64_export(data, this._settings.xhtml_path+fname))
						break;
					// image export was successful, continue to next page
					else { ++done; continue; }
				}
			} else
				data = woas.export_parse(data, this._settings.js_mode);
			if (!this._one_page(data, page_titles[pi], fname, woas.config.store_mts ? page_mts[pi] : 0))
				break;
			++done;
		}
		log("pages yet to process: "+this._further_pages);	// log:1
		// process further pages
		var title;
		// exchange arrays to parse at some extent
		var eatable = this._further_pages.slice(0);
		while (eatable.length) {
			this._further_pages = [];
			for(var i=0,el=eatable.length;i < el;i++) {
				title = eatable[i];
				data = woas.get_text_special(title);
				if (data===null) {
					log("cannot process "+title);
					continue;
				}
				// TODO: allow special pages to have extended attributes
				data = woas.export_parse(data, this._settings.js_mode);
				++total;
				if (this._one_page(data, title, this._title2fn[title]))
					++done;
			}
			eatable = this._further_pages.slice(0);
		}
		// return total exported pages/objects
		return [done, total];
	},
	
	_one_page: function (data, title, fname, mts) {
		data = woas.utf8.do_escape(data);
		// prepare the raw text for later description/keywords generation
		var raw_text = woas.trim(woas.xhtml_to_text(data));
		if (this._settings.exp_menus) {
			var _exp_menu = woas.get_text("::Menu");
			if (_exp_menu === null)
				_exp_menu = "";
			var _ns = woas.get_namespace(title);
				if (_ns.length) {
					var mpi = woas.page_index(_ns+"::Menu");
					if (mpi !== -1) {
						var tmp=woas.get_text_special(_ns+"::Menu");
						if (tmp!==null)
							_exp_menu += tmp;
					}
				}
				// parse the exported menu
				if (_exp_menu.length) {
					_exp_menu = woas.parser.parse(_exp_menu, true, this._settings.js_mode);
					if (this._settings.js_mode)
						woas._activate_scripts();
					// fix also the encoding in the menus
					_exp_menu = woas.utf8.do_escape(_exp_menu);
				}
				//TODO: use correct ids/class names
				data = '<'+'div id="i_woas_menu_area" style="position: absolute;"><'+'div class="woas_wiki" id="woas_menu_area">'+_exp_menu+'<'+'/div><'+
						'/div><'+'div class="woas_text_area" id="woas_wiki_area">'+data+'<'+'/div>';
			}
			// craft a nice XHTML page
			data = "<"+"title>"+woas.xhtml_encode(title)+"<"+"/title>"+
					// add the exported CSS
					this._settings.css+
					// add the last-modified header
					(mts ? '<'+'meta http-equiv="last-modified" content="'+
					(new Date(mts*1000)).toGMTString()+'" />'+"\n" : '')+
					// other useful META stuff
			'<'+'meta name="generator" content="Wiki on a Stick v'+woas.version+' - http://stickwiki.sf.net/" />'+"\n"+
			'<'+'meta name="keywords" content="'+woas.utf8.do_escape(woas._attrib_escape(_auto_keywords(raw_text)))+'" />'+"\n"+
			'<'+'meta name="description" content="'+
			woas.utf8.do_escape(woas._attrib_escape(raw_text.replace(/\s+/g, " ").substr(0,max_description_length)))+'" />'+"\n"+
			this._settings.meta_author+
			this._settings.custom_scripts+
			'<'+'/head><'+'body>'+data+
			(mts ? "<"+"div class=\"woas_page_mts\">"+woas.last_modified(mts)+"<"+"/div>" : "")+
			"<"+"/body><"+"/html>\n"; raw_text = null;
		return woas.save_file(this._settings.xhtml_path+fname, woas.file_mode.ASCII, woas.DOCTYPE+woas.DOC_START+data);
	},
	
	_get_fname: function (title, create_mode) {
		if (typeof(this._title2fn[title]) != 'undefined') {
			// return a cached title
			if (!create_mode) {
				// do not escape the null-page URL
				if (this._title2fn[title] == '#')
					return '#';
				return escape(this._title2fn[title]);
			}
			return this._title2fn[title];
		}
		var sp, orig_title = title;
		// handle the valid exportable special pages
		if (title.match(/::$/))
			sp = true;
		else if (woas.is_reserved(title)) {
			var nogo;
			if (title.match(/^WoaS::/))
				nogo = (woas.unexportable_pages2.indexOf(title)!==-1);
			else if (title.match(/^Special::/))
				nogo = (woas.unexportable_pages.indexOf(title.substr(9)) !== -1);
			else // other reserved pages, deny
				nogo = true;
			if (nogo) {
				log("Reserved page will not be exported: "+title);
				this._title2fn[title] = "#";
				return "#";
			} else // do export these special pages later
				sp = true;
		}
		var pi;
		if (sp) {
			// save a reference to this namespace or reserved page
			if (this._further_pages.indexOf(title)==-1)
				this._further_pages.push(title);
		} else {
			pi=woas.page_index(title);
			if (pi === -1) {
				woas.alert(woas.i18n.PAGE_NOT_EXISTS+title);
				this._title2fn[title] = "#";
				return "#";
			}
			// beware: a special page or namespace index page cannot be main page
			// considering the below code
			if (this._settings._main_index && (title === woas.config.main_page)) {
				this._title2fn[title] = "index."+ this._default_ext;
				this._export_fnames_array.push(this._title2fn[title]);
				return this._title2fn[title];
			}
		}
		var ext = "";
		if (!sp && woas.is__embedded(pi)) {
			// remove the namespace
			title = title.substr(title.indexOf("::")+2);
	//		if (!this.is__image(pi))
	//			ext = "."+this._default_ext;
	//		emb = true;
		} else {
			ext = "."+this._default_ext;
	//		emb = false;
		}
		var fname = title
		// convert UTF8 characters to something else (cross-browser safe cheap solution)
		.replace(/[^\u0000-\u007F]+/g, function ($1) {
			var l=$1.length, r="";
			for(var i=0;i < l;i++) {
				/*switch ($1[i]) {
					// TODO: add most common diacritics
					case "\u00e2":
						r+="a";
						break;
					default:
						r+="_";
				}*/
				// until that day ...
				r += ($1[i] == "\u00e2") ? "a" : "_";
			}
			return r;
		})
		// escape some path-unsafe characters
		.replace(/[:\\\/<>?#=!]+/g, function($1) {
			return "_".repeat($1.length);
		});
		// fix the directory separator chars
		if (this._settings._unix_norm)
			fname = woas._unix_normalize(fname);
		else
			fname = fname.replace(/::/g, " - ");
		var test_fname = fname+ext, i=0;
		while (this._export_fnames_array.indexOf(test_fname) !== -1) {
			log(test_fname+" already created, checking next fname");	// log:1
			test_fname = fname+"_".repeat(++i)+ext;
		}
	//	if (i)		_export_replace_fname[fname+"_".repeat(i-1)+ext] = test_fname;
		this._export_fnames_array.push(test_fname);
		this._title2fn[orig_title] = test_fname;
		if (!create_mode)
			return escape(test_fname);
		return test_fname;
	}

};

woas._unix_normalize = function(s) {
	return s.toLowerCase().replace(/\s+/g, "_").replace(/::/g, "-")
};

// save a base64 data: stream into an external file
woas._b64_export = function(data, dest_path) {
	// decode the base64-encoded data
	data = this.base64.decode(data.replace(/^data:\s*[^;]*;\s*base64,\s*/, ''));
	// attempt to save the file
	return this.save_file(dest_path, this.file_mode.BINARY, data);
};

woas._attrib_escape = function(s) {
	return s.replace(/"/g, '&quot;');
};

woas.export_parse = function (data, js_mode) {
	// a normal wiki page, parse it and eventually execute the attached javascript
	data = this.parser.parse(data, true, js_mode);
	if (js_mode) {
		this.setHTMLDiv(d$("woas_wiki_area"), data);
		this._activate_scripts();
		data = this.getHTMLDiv(d$("woas_wiki_area"));
	}
	return data;
};

woas.export_wiki = function() {
	var sep_css;
	// parse user export options
	try {
		this.exporter._settings.xhtml_path = d$("woas_ep_xhtml").value;
		this.exporter._settings.img_path = d$("woas_ep_img").value;
		this.exporter._settings.js_mode = 0;
		if (d$("woas_cb_js_dyn").checked)
			this.exporter._settings.js_mode = 1;
		else if (d$("woas_cb_js_exp").checked)
			this.exporter._settings.js_mode = 2;
		sep_css = d$("woas_cb_sep_css").checked;
		this.exporter._settings.exp_menus = d$("woas_cb_export_menu").checked;
		this.exporter._settings._main_index = d$("woas_cb_index_main").checked;
		this.exporter._default_ext = d$("woas_ep_ext").value;
		this.exporter._settings.meta_author = this.trim(d$("woas_ep_author").value);
		if (this.exporter._settings.meta_author.length)
			this.exporter._settings.meta_author = '<'+'meta name="author" content="'+this._attrib_escape(this.xhtml_encode(this.exporter._settings.meta_author))+'" />'+"\n";
		this.exporter._settings._unix_norm = d$("woas_cb_unix_norm").checked;
	} catch (e) { this.crash(e); return false; }
	
	this.progress_init("Exporting XHTML");

	this.exporter._settings.css = this.css.get();
	// add some other CSS which is not used by live WoaS
	this.exporter._settings.css += "\n.woas_broken_link { color: red; font-decoration: strike-through;}\n";
	if (sep_css) {
		this.exporter._settings.css_path = "woas.css";
		this.exporter._export_fnames_array.push(this.exporter._settings.css_path);
		this.save_file(this.exporter._settings.xhtml_path+this.exporter._settings.css_path, this.file_mode.ASCII, this.exporter._settings.css);
		this.exporter._settings.css = "<"+"link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\""+this.exporter._settings.css_path+"\" /"+">";
		} else
	this.exporter._settings.css = "<"+"style type=\"text/css\">"+this.exporter._settings.css+"<"+"/style>";
	
	// actual exporting
	var stats = this.exporter.do_export();
	
	// clear allocated resources during export
	this.exporter.clear();
	
	// refresh if javascript was ran
	if (this.exporter._settings.js_mode) {
		this.refresh_menu_area();
		this.set_current(current, false);
	}
	this.progress_finish();
	this.alert(this.i18n.EXPORT_OK.sprintf(stats[0], stats[1]));
	return true;
};

var max_keywords_length = 250;
var max_description_length = 250;
// proper autokeywords generation functions begin here
var reKeywords = new RegExp("[^\\s\x01-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]{2,}", "g");
function _auto_keywords(source) {
	if (!source.length) return "";
	var words = source.match(reKeywords);
	if ((words===null) || !words.length) return "";
	var nu_words = [], density = [], wp=0, cond;
	for(var i=0;i < words.length;i++) {
		if (words[i].length === 0)
			continue;
		cond = (woas.i18n.common_words.indexOf(words[i].toLowerCase())<0);
		if (cond) {
			wp = nu_words.indexOf(words[i]);
			if (wp < 0) {
				nu_words = nu_words.concat(new Array(words[i]));
				density[nu_words.length-1] = {"i":nu_words.length-1, "w":1};
			} else
				density[wp].w = density[wp].w + 1;
		}
	}
	if (!density.length) return "";
	words = [];
	var keywords = "", nw = "";
	density = density.sort(function(a,b){return b.w - a.w;});
	var ol=0;
	for(i=0;i < density.length;i++) {
		nw = nu_words[density[i].i];
		if (ol+nw.length > max_keywords_length)
			break;
		keywords = keywords+","+nw;
		ol+=nw.length;
	}
	return keywords.substr(1);
}

// used to export files/images
woas.export_file = function(page, dest_path) {
	var pi=this.page_index(page);
	if (pi==-1)
		return false;
	var data=this.get__text(pi);
	if (data==null)
		return false;
	// attempt to save the file (binary mode)
	return this.save_file(dest_path, this.file_mode.BINARY, this.base64.decode(data));
};

// export a base64-encoded image to a file
woas.export_image = function(page, dest_path) {
	var pi=this.page_index(page);
	if (pi==-1)
		return false;
	var data=this.get__text(pi);
	if (data==null)
		return false;
	return this._b64_export(data, dest_path);
};

/*** src/wsif.js ***/
// @module wsif

woas.wsif = {
	version: "1.3.1",			// version of WSIF format being used
	DEFAULT_INDEX: "index.wsif",
	emsg: null,
	imported: [],				// _native_page_def() will always add imported pages here
	expected_pages: null,
	global_progress: 0,
	generator: { version: null, name: null },
	header: function(header_name, value) {
		return header_name+": "+value+"\n";
	},
	inline: function(boundary, content) {
		return "\n--"+boundary+"\n"+content+"\n--"+boundary+"\n";
	},
	_generate_random_boundary: function(old_boundary, text) {
		var b = old_boundary;
		if (!b.length)
			b = _random_string(10);
		while (text.indexOf(b) != -1) {
			b = _random_string(10);
		}
		return b;
	},
	do_error: function(msg) {
		woas.log("WSIF ERROR: "+msg);	//log:1
		this.emsg = msg;
	},
	
	reMimeMatch: /^data:\s*([^;]*);\s*base64,\s*/
};

// properly calculate an incremental value for version strings
// we consider each place is worth 10^2
woas._version_to_int = function(s) {
	// split into all tokens
	var v = s.split("."), rv = 0;
	for(var i=v.length-1;i >= 0;--i) {
		rv += (v[i] * Math.pow(100, v.length-i-1));
	}
	return rv;
};

woas._normver = function(s) {
	// to be enabled after 1.0.0 release
	//var rv = this._version_to_int(s);
	//if (rv >= 10000) return rv;
	return parseInt(s.replace(/\./g, ""));
};

// default behavior:
// - wiki pages go inline (utf-8), no container encoding
// - embedded files/images go outside as blobs
// - encrypted pages go inline in base64
woas._native_wsif_save = function(path, src_fname, locking, single_wsif, inline_wsif, author,
							save_all, plist) {

	this.progress_init("WSIF save");
	
	// prepare the extra headers
	var extra = this.wsif.header('wsif.version', this.wsif.version);
	extra += this.wsif.header('wsif.generator', 'woas');
	extra += this.wsif.header('wsif.generator.version', this.version);
	if (author.length)
		extra += this.wsif.header('woas.author', author);

	// boundary used for inline attachments
	var full_wsif = "", boundary = __marker,
		p = boundary.indexOf("-"),
		l, done = 0, full_save;
	// use the 1st part of the global marker
	if (p !== -1)
		boundary = boundary.substr(0,p);

	if (typeof plist == "undefined") {
		full_save = true;
		l = page_titles.length;
	} else {
		l = plist.length;
		full_save = false;
	}
	// save count of total pages which need to be exported
	this.wsif.expected_pages = l;
	// the attributes prefix, we do not use the page index here for better versioning
	var pfx = "woas.page.",
		pi, pl;
	for (var ipi=0;ipi < l;++ipi) {
		if (full_save)
			pi = ipi;
		else
			pi = plist[ipi];
		// do skip physical special pages
		if (!save_all) {
			if (page_titles[pi].match(/^Special::/)) continue;
			if (this.static_pages2.indexOf(page_titles[pi]) !== -1) continue;
			if (page_titles[pi].match(/^WoaS::Help::/)) continue;
		}
		var record = this.wsif.header(pfx+"title", this.ecma_encode(page_titles[pi]))+
					this.wsif.header(pfx+"attributes", page_attrs[pi]);
		// specify timestamp only if not magic
		if (this.config.store_mts && (page_mts[pi] !== 0))
			record += this.wsif.header(pfx+"last_modified", page_mts[pi]);
		var ct = null, orig_len = null;
		
		// normalize the page content, set encoding&disposition
		var encoding = null, mime = null, disposition = "inline";
		if (this.is__encrypted(pi)) {
			ct = this.base64.encode_array(pages[pi]);
			encoding = "8bit/base64";
			// special header used for encrypted pages
			orig_len = pages[pi].length;
		} else {
			ct = pages[pi];
			if (this.is__embedded(pi)) {
				// if not forced to do them inline, convert for export
				var m;
				if (!inline_wsif) {
					disposition = "external";
					encoding = "8bit/plain";
					// decode the base64-encoded data
					if (this.is__image(pi)) {
						m = ct.match(this.wsif.reMimeMatch);
						record += this.wsif.header(pfx+"mime", m[1]);
						// remove the matched part
						ct = this.base64.decode(ct.substr(m[0].length));
					} else { // no data:uri for files
						ct = this.base64.decode(ct);
					}
				} else {
					encoding = "8bit/base64";
					if (this.is__image(pi)) {
						m = ct.match(this.wsif.reMimeMatch);
						if (m === null) {
							this.crash(page_titles[pi]+" is not a valid image!"+ct);							
							continue;
						} else {
							mime = m[1];
							// remove the matched part
							ct = ct.substr(m[0].length);
							m = null;
						}
						record += this.wsif.header(pfx+"mime", mime);
					}
				}
			} else { // normal wiki pages
				// check if ECMA encoding is necessary
				if (this.needs_ecma_encoding(ct)) {
					ct = this.ecma_encode(ct);
					encoding = "ecma/plain";
				} else
					encoding = "8bit/plain";
			}
		}
		//DEBUG check
		if (encoding === null) {
			this.crash("Encoding for page "+page_titles[pi]+" is set to null!");
			continue;
		}
		// update the index (if needed)
		if (!single_wsif && full_save) {
			full_wsif += this.wsif.header(pfx+"title", this.ecma_encode(page_titles[pi]));
			// a new mime type
			full_wsif += this.wsif.header(pfx+"encoding", "text/wsif");
			full_wsif += this.wsif.header(pfx+"disposition", "external");
			// add reference to the external WSIF file
			full_wsif += this.wsif.header(pfx+"disposition.filename", pi.toString()+".wsif")+
							"\n";
		}
		// update record
		if (!this.config.allow_diff)
			record += this.wsif.header(pfx+"length", ct.length);
		record += this.wsif.header(pfx+"encoding", encoding);
		record += this.wsif.header(pfx+"disposition", disposition);
		// note: when disposition is inline, encoding cannot be 8bit/plain for embedded/encrypted files
		if (disposition == "inline") {
			// output the original length header (if available)
			if (orig_len !== null)
				record += this.wsif.header(pfx+"original_length", orig_len);
			// create the inline page
			boundary = this.wsif._generate_random_boundary(boundary, ct);
			record += this.wsif.header(pfx+"boundary", boundary);
			// add the inline content
			record += this.wsif.inline(boundary, ct); ct = null;
		} else {
			// create the blob filename
			var blob_fn = "blob" + pi.toString() + woas._file_ext(page_titles[pi]);
			// specify path to external filename
			record += this.wsif.header(pfx+"disposition.filename", blob_fn)+"\n";
			// export the blob
			if (!this.save_file(path + blob_fn,
							(encoding === "8bit/plain") ?
							this.file_mode.BINARY : this.file_mode.ASCII_TEXT, ct))
				woas.log("Could not save "+blob_fn);	//log:1
			// release any lock held previously
			if (locking)
				this.lock.release(path+blob_fn);
		}
		// the page record is now ready, proceed to save
		if (single_wsif) {// append to main page record
			full_wsif += record;
			++done;
		} else { // save each page separately
			if (this.save_file(path+pi.toString()+".wsif",
								this.file_mode.ASCII_TEXT,
								// also add the pages counter (single)
								extra + this.wsif.header("woas.pages", 1) +
								"\n" + record))
				++done;
		}
		this.progress_status(done/l);
		// reset the record
		record = "";
	} // foreach page
	// add the total pages number
	if (full_save || single_wsif)
		extra += this.wsif.header('woas.pages', done);
	else
		extra += this.wsif.header('woas.pages', page_titles.length);
	// build (artificially) an index of all pages
	if (!full_save && !single_wsif) {
		for (pi=0,pl=page_titles.length;pi<pl;++pi) {
			full_wsif += this.wsif.header(pfx+"title", this.ecma_encode(page_titles[pi]));
			// a new mime type
			full_wsif += this.wsif.header(pfx+"encoding", "text/wsif");
			full_wsif += this.wsif.header(pfx+"disposition", "external");
			// add reference to the external WSIF file
			full_wsif += this.wsif.header(pfx+"disposition.filename", pi.toString()+".wsif")+
							"\n";
		}
	}
	// output the index WSIF file now
	if (!this.save_file(path+src_fname,
						this.file_mode.ASCII_TEXT,
						extra + "\n" + full_wsif)) {
		if (single_wsif)
			done = 0;
	} // we do not increment page counter when saving index.wsif
	
	// release any lock held previously
	if (locking)
		this.lock.release(path+src_fname);
	
	this.progress_finish();
	return done;
};

woas._wsif_ds_load = function(subpath, locking) {
	// we reset the arrays before loading the real data from index.wsif
	pages = [];
	page_attrs = [];
	page_titles = [];
	page_mts = [];
	// get the data
	return this._native_wsif_load(woas.ROOT_DIRECTORY+subpath, locking, true, 0,
			this.importer._inject_import_hook);
};

/* description of parameters:
 - path: WSIF file path which will be loaded, can be null to use file specified in '_filename' element
 - locking: resource locking (not yet implemented)
 - _native: true when WoaS is in native mode (private use only)
 - recursing: recursion depth variable, starts with 0
 - import_hook: callback used to actually import the page
 - title_filter_hook: callback used to choose if page can be imported or not by title - optional
 - finalization_hook: callback used when import is finished
*/
woas._native_wsif_load = function(path, locking, _native, recursing, import_hook,
								title_filter_hook, finalization_hook) {
	if (!recursing) {
		this.wsif.emsg = null;
		this.progress_init("Initializing WSIF import");
	}
	var ct;
	// allow remote loading when running in native WSIF mode
	if (this._server_mode && (this.config.wsif_ds.length !== 0))
		ct = this.remote_load(path);
	else
		ct = this.load_file(path, this.file_mode.ASCII_TEXT);
	if (typeof ct != "string") {
		if (!recursing)
			this.progress_finish();
		if (ct === false)
			this.alert(this.i18n.LOAD_ERR);
		return false;
	}
	// reset when not recursing
	if (!recursing) {
		this.wsif.expected_pages = null;
		this.wsif.emsg = this.i18n.NO_ERROR;
		this.wsif.imported = [];
		this.wsif.global_progress = 0;
		this.wsif.generator = { version: null, name: null };
	}
	var pfx = "\nwoas.page.", pfx_len = pfx.length;
	// start looping to find each page
	var p = ct.indexOf(pfx), fail = false,
	// this is used to mark end-of-block
		previous_h = null;
	// too early failure
	if (p === -1)
		this.wsif.do_error("Invalid WSIF file");
	else { // OK, first page was located, now get some general WSIF info
		var wsif_v = ct.substring(0,p).match(/^wsif\.version:\s+(.+)$/m);
		if (wsif_v === null) {
			this.wsif.do_error(this.i18n.WSIF_NO_VER);
			p = -1;
			fail = true;
		} else {
			// convert to a number
			wsif_v = wsif_v[1];
			var wsif_v_n = this._normver(wsif_v);
			// check if WSIF is from future of it is the unsupported 1.0.0
			if ((wsif_v_n == 100) || (wsif_v_n > this._normver(this.wsif.version))) {
				this.wsif.do_error(this.i18n.WSIF_NS_VER.sprintf(wsif_v));
				p = -1;
				fail = true;
			} else {
				if (!recursing) {
					// get number of expected pages
					this.wsif.expected_pages = ct.substring(0,p).match(/^woas\.pages:\s+(\d+)$/m);
					if (this.wsif.expected_pages !== null)
						this.wsif.expected_pages = Number(this.wsif.expected_pages[1]);
					// gather generator information
					this.wsif.generator.name = ct.substring(0,p).
						match(/^wsif\.generator:\s+(.+)$/m);
					if (this.wsif.generator.name !== null) {
						this.wsif.generator.name = this.wsif.generator.name[1];
						this.wsif.generator.version = ct.substring(0,p).
							match((wsif_v_n < 131) ? /^woas\.version:\s+(.+)$/m : /^wsif\.generator\.version:\s+(.+)$/m);
						if (this.wsif.generator.version !== null) {
							this.wsif.generator.version = this.wsif.generator.version[1];
						}
					}

					// was generator information truly necessary?
					if (this.wsif.generator.name === "woas") {
						if (this.wsif.generator.version === null) {
							this.wsif.do_error("WSIF generator version is not available");
							p = -1;
							fail = true;
						} else {
							if (!_native)
								// copy to importer module
								this.importer._old_version = this._normver(this.wsif.generator.version);
							else { // native mode
								if (this.wsif.generator.version !== this.version) {
									this.wsif.do_error("WSIF generator version should match WoaS version");
									p = -1;
									fail = true;
								}
							}
						}
					} else {
						if (!_native) {
							// assume that any content generated with libwsif is up-to-date for import
							this.importer._old_version = this._normver(this.version);
						} else { // native mode
							this.wsif.do_error("WSIF generator is not 'woas'");
							p = -1;
							fail = true;
						}
					}

				} // !recursing
			} // valid version
		} // has version
	}
	var title = null,	attrs = null,
		last_mod = null,	len = null,
		encoding = null,	disposition = null,
		d_fn = null,	boundary = null,	mime = null;
	// position of last header end-of-line
	var sep, s, v, last_offset;
	while (p !== -1) {
		// save last entry offset, used by page definition
		last_offset = p;
		// remove prefix
		sep = ct.indexOf(":", p+pfx_len);
		if (sep === -1) {
			this.wsif.do_error(this.i18n.WSIF_NO_HN);
			fail = true;
			break;
		}
		// get attribute name
		s = ct.substring(p+pfx_len, sep);
		// get value
		p = ct.indexOf("\n", sep+1);
		if (p == -1) {
			this.wsif.do_error(this.i18n.WSIF_BAD_HV);
			fail = true;
			break;
		}
		// all headers except the title header can mark an end-of-block
		// the end-of-block is used to find boundaries and content inside
		// them
		if (s != "title")
			// save the last header position
			previous_h = p;
		// get value and apply left-trim
		v = ct.substring(sep+1, p).replace(/^\s*/, '');
		switch (s) {
			case "title":
				// we have just jumped over a page definition
				if (title !== null) {
					// do not import special/reserved pages
					var skip_page;
					if (typeof title_filter_hook == "function")
						skip_page = !title_filter_hook(title);
					else skip_page = false;
					if (skip_page) {
						title = attrs = last_mod = encoding = len =
							 boundary = disposition = mime = d_fn = null;
					} else {
						// store the previously parsed page definition
						var rv = this._native_page_def(path,ct,
								previous_h, last_offset,	// offsets to grab the page content
								import_hook,
								title,attrs,last_mod,len,encoding,disposition,
								d_fn,boundary,mime);
						// save page index for later analysis
						var was_title = title;
						title = attrs = last_mod = encoding = len =
							 boundary = disposition = mime = d_fn = null;
						if (!rv) // show a message but continue parsing
							woas.log("Import failure for "+was_title); //log:1
					}
					// delete the whole entry to free up memory to GC
					// will delete also the last read header (p != last_offset)
					ct = ct.substr(p);
					last_offset = p = 0;
					previous_h = null;
					// update status if not recursing
					if (!recursing && (this.wsif.expected_pages !== null))
						this.progress_status(this.wsif.global_progress++/this.wsif.expected_pages);
				}
				// let's start with the next page
				title = this.ecma_decode(v);
			break;
			case "attributes":
				attrs = Number(v);
			break;
			case "last_modified":
				if (this.config.store_mts)
					last_mod = Number(v);
			break;
			case "length":
				len = Number(v);
			break;
			case "encoding":
				encoding = v;
			break;
			case "disposition":
				disposition = v;
			break;
			case "disposition.filename":
				//TODO: ecma-escape
				d_fn = v;
			break;
			case "boundary":
				boundary = v;
			break;
			case "mime":
				mime = v;
			break;
			case "original_length":
				// this should be used for trimming base64 encrypted pages
				// ignored for now
			break;
			default:
				woas.log("Unknown WSIF header: "+s);	//log:1
		} // end switch(s)
		if (fail)
			break;
		// set pointer to next entry
		p = ct.indexOf(pfx, p);
	}
	if (fail) {
		if (!recursing)
			this.progress_finish();
		return false;
	}
	// process the last page (if any)
	if ((previous_h !== null) && (title !== null)) {
		var skip_page;
		if (typeof title_filter_hook == "function")
			skip_page = !title_filter_hook(title);
		else skip_page = false;
		if (!skip_page) {
			var rv = this._native_page_def(path,ct,previous_h,last_offset,
					import_hook,
					title,attrs,last_mod,len,encoding,disposition,
					d_fn,boundary,mime);
			// save page index for later analysis
			if (!rv)
				this.wsif.do_error( "Import error for page "+title+" after import!" );
			// update status if not recursing
			if (!recursing && (this.wsif.expected_pages !== null))
				this.progress_status(this.wsif.global_progress++/this.wsif.expected_pages);
		}
	}
	if (!recursing) {
		this.progress_finish();
		// call the finalization callback (if any)
		if (typeof finalization_hook == "function")
			finalization_hook();
	}
	// return total imported pages
	return this.wsif.imported.length;
};

// returns true if a page was defined, and save it in wsif.imported array
woas._native_page_def = function(path,ct,p,last_p,import_hook,
								title,attrs,last_mod,len,encoding,disposition,d_fn,boundary,mime) {
	var bpos_e, page;
	// attributes must be defined
	if (attrs === null) {
		woas.log("No attributes defined for page "+title);	//log:1
		return false;
	}
	// disposition must be defined
	if (disposition === null) {
		woas.log("No disposition defined for page \""+title+"\"");	//log:1
		return false;
	}
	// last modified timestamp can be omitted
	if (last_mod === null)
		last_mod = 0;
		
	switch (disposition) {
		case "inline":
		// craft the exact boundary match string
		boundary = "\n--"+boundary+"\n";
		// locate start and ending boundaries
		var bpos_s = ct.indexOf(boundary, p);
		if (bpos_s == -1) {
			this.wsif.do_error( "Failed to find start boundary "+boundary+" for page "+title );
			return false;
		}
		bpos_e = ct.indexOf(boundary, bpos_s+boundary.length);
		if (bpos_e == -1) {
			this.wsif.do_error( "Failed to find end boundary "+boundary+" for page "+title );
			return false;
		}
		// retrieve full page content
		page = ct.substring(bpos_s+boundary.length, bpos_e);
		// length used to check correctness of data segments
		var check_len = page.length;
		// split encrypted pages into byte arrays
		if (attrs & 2) {
			if (encoding != "8bit/base64") {
				woas.log("Encrypted page "+title+" is not encoded as 8bit/base64");	//log:1
				return false;
			}
//			check_len = page.length;
			page = this.base64.decode_array(page);
			// trim to correct length
			// perhaps we could use woas.page.original_length field
			// also, we could not make this check if version is 0.10.4
			// but for now it's a good safety
			var rest = page.length % 16;
			if (rest)
				woas.log("NOTICE: removing "+rest+" trailing bytes from page "+title); //log:1
			while (rest-- > 0) {page.pop();}
		} else if (attrs & 8) { // embedded image, not encrypted
			// NOTE: encrypted images are not obviously processed, as per previous 'if'
			if (encoding != "8bit/base64") {
				woas.log("Image "+title+" is not encoded as 8bit/base64");	//log:1
				return false;
			}
			if (mime === null) {
				woas.log("Image "+title+"has no mime type defined");		//log:1
				return false;
			}
			// re-add data:uri to images
			page = "data:"+mime+";base64,"+page;
		} else { // a normal wiki page
			switch (encoding) {
				case "8bit/base64":
					// base64 files will stay encoded
					if (!(attrs & 4))
						// WoaS does not encode pages normally, but this is supported by WSIF format
						page = this.base64.decode(page);
				break;
				case "ecma/plain":
					page = this.ecma_decode(page);
				break;
				case "8bit/plain": // plain wiki pages are supported
				break;
				default:
					woas.log("Normal page "+title+" comes with unknown encoding "+encoding);	//log:1
					return false;
			}
		}
		// check length (if any were passed)
		if (len !== null) {
			if (len != check_len)
				// show a simple log message
				woas.log("Length mismatch for page %s: ought to be %d but was %d".sprintf(title, len, check_len)); //log:1
		}
		// fallback wanted to go to define the page
	break;
	case "external":	// import an external WSIF file
		if (d_fn === null) {
			this.wsif.do_error( "Page "+title+" is external but no filename was specified");
			return false;
		}
		// use last filename to get path
		var the_dir;
		if (path === null) {
			the_dir = this._get_path("filename_");
			if (the_dir === false) {
				this.wsif.do_error( "Cannot retrieve path name in this browser");
				return false;
			}
		} else {
			this.wsif.do_error( "Recursive WSIF import not implemented");
			return false;
		}
		// embedded image/file, not encrypted
		if ((attrs & 4) || (attrs & 8)) {
			if (encoding !== "8bit/plain") {
				this.wsif.do_error( "Page "+title+" is an external file/image but not encoded as 8bit/plain");
				return false;
			}
			// load file and apply base64 encoding if embedded
			var wanted_mode;
			// images
			if ((attrs & 4) && (attrs & 8))
				wanted_mode = this.file_mode.DATA_URI;
			// files
			else if (attrs & 4)
				wanted_mode = this.file_mode.BASE64;
			else // dunnowhat
				wanted_mode = this.file_mode.BINARY;
			page = this.load_file(the_dir+d_fn, wanted_mode, mime);
			if (typeof page != "string") {
				this.wsif.do_error( "Failed load of external "+the_dir+d_fn);
				return false;
			}
			// fallback wanted to apply real page definition later
		} else {
			if (encoding != "text/wsif") {
				this.wsif.do_error( "Page "+title+" is external but not encoded as text/wsif");
				return false;
			}
			// check the result of external import
			var rv = this._native_wsif_load(the_dir+d_fn, locking, _native,
											1, import_hook, title_filter_hook);
			if (rv === false)
				this.wsif.do_error( "Failed import of external "+the_dir+d_fn);
			// return pointer after last read header
			return rv;
		}
	break;
	default: // no disposition or unknown disposition
		this.wsif.do_error( "Page "+title+" has invalid disposition: "+disposition);
		return false;
	} // end of switch

	// create the page object
	var NP = { "title": title, "attrs": attrs, "body": page, "mts": last_mod };
	
	// check that this was imported successfully
	if (import_hook( NP ) ) {
		// all OK
		this.wsif.imported.push(NP.i);
		return true;
	}

	return false;
};

/*** src/legacy.js ***/
// deprecated/legacy functions

//DEPRECATED but still supported
var log = woas.log;

//DEPRECATED
function home() {
	woas.log("WARNING: Called deprecated function: home");
	woas.ui.home();
}

//DEPRECATED
function help() {
	woas.log("WARNING: Called deprecated function: help");
	woas.ui.help();
}

// when Advanced is clicked
//DEPRECATED
function advanced() {
	woas.log("WARNING: Called deprecated function: advanced");
	woas.ui.advanced();
}

//DEPRECATED
function go_to(t) {
	woas.log("WARNING: Called deprecated function: go_to");
	return woas.go_to(t);
}
//DEPRECATED
function go_back() {
	woas.log("WARNING: Called deprecated function: go_back");
	woas.ui.back();
}
//DEPRECATED
function go_forward() {
	woas.log("WARNING: Called deprecated function: go_forward");
	woas.ui.forward();
}
//DEPRECATED
function edit() {
	woas.log("WARNING: Called deprecated function: edit");
	woas.ui.edit();
}

//DEPRECATED
function lock() {
	woas.log("WARNING: Called deprecated function: lock");
	woas.ui.lock();
}

//DEPRECATED
function unlock() {
	woas.log("WARNING: Called deprecated function: unlock");
	woas.ui.unlock();
}

//DEPRECATED
function save() {
	woas.log("WARNING: Called deprecated function: save");
	woas.save();
}

// old tables parsing syntax - DEPRECATED
var reReapTables = /^\{\|.*((?:\n\|.*)*)$/gm,
	reReapTableRows = /\n\|([+ -])(.*)/g;
woas.parser.parse_tables =  function (str, p1) {
	var caption = false,
		stk = [];
	p1.replace(reReapTableRows, function(str, pp1, pp2) {
			if (pp1 == '-')
				return;
			else if (pp1 == '+') {
				caption = caption || pp2;
				return;
			}
			stk.push('<'+'td>' + pp2.split('||').join('<'+'/td><'+'td>') + '<'+'/td>');
		} 
	);
	if (stk.length)
		return  '<'+'table class="woas_text_area">' +
				(caption?('<'+'caption>' + caption + '<'+'/caption>'):'') +
				'<'+'tr>' + stk.join('<'+'/tr><'+'tr>') + '<'+'/tr>' +
			'<'+'/table>';
	return str;
};

/*** src/ui.js ***/
// @module ui
// User Interface bindings
woas.ui = {
	edit_mode: false,		// set to true when inside an edit textarea
	_textbox_focus: false,	// true when a text box is currently focused
	focus_textbox: function() { // called when a textbox has currently focus
		this._textbox_focus = true;
	},
	blur_textbox: function() { // called when a textbox looses focus
		this._textbox_focus = false;
		ff_fix_focus();
		// reset event handler
		this._textbox_enter_event = this._textbox_enter_event_dummy;
	},
	// event (to be overriden) to run in case of enter key pressed
	// for example, searching
	_textbox_enter_event_dummy: function() {
	},
	_textbox_enter_event: null,
	// custom event handler which can be overriden to process the keypresses
	_custom_key_hook: function(orig_e) {
		// continue parsing as normal
		return true;
	},
	
	// event called on key press
	//NOTE: since this is attached directly to DOM, you should not use 'this'
	_keyboard_event_hook: function(orig_e) {
		if (!orig_e)
			e = window.event;
		else
			e = orig_e;
		var ck = woas.browser.ie ? e.keyCode : e.which;
		
		if (!woas.ui.edit_mode) {
			// there is a custom focus active, call the hook
			// and return if it told us to do so
			if (!woas.ui._custom_key_hook(orig_e))
				return orig_e;
			if (woas.ui._textbox_focus) {
				// return key
				if (ck == 13) {
					// clear focus
					ff_fix_focus();
					// run attached event
					(woas.ui._textbox_enter_event)();
					return false;
				}
				return orig_e;
			}
			// back or cancel keys
			if ((ck == woas.hotkey.all.back) || (ck == woas.hotkey.all.cancel)) {
				go_back();
				ff_fix_focus();
				return false;
			}
		}
		// cancel key
		if (ck == woas.hotkey.all.cancel) {
			woas.ui.cancel();
			ff_fix_focus();
			return false;
		}

		return orig_e;
	},
	// could have a better name
	help: function() {
		var wanted_page, pi;
		// we are editing
		if (this.edit_mode) {
			wanted_page = "WoaS::Help::Editor";
			pi = woas.page_index(wanted_page);
		} else {
			var htitle = null;
			// change the target page in some special cases
			if (current.substr(0, 6) === "WoaS::") {
				if (woas.help_system._help_lookup.indexOf(current.substr(6)) !== -1)
					htitle = current.substr(6);
				else
					htitle = current;
			} else htitle = current;
			var npi = woas.page_index("WoaS::Help::"+htitle);
			if (npi !== -1) {
				wanted_page = "WoaS::Help::"+htitle;
				pi = npi;
			} else {
				wanted_page = "WoaS::Help::Index";
				pi = woas.page_index(wanted_page);
			}
		}
		woas.help_system.go_to(wanted_page, pi);
	},
	tables_help: function() {
		woas.help_system.go_to("WoaS::Help::Tables");
	},
	clear_search: function(no_render) {
//		woas.log("Clearing search"); //log:0
		if (current === "Special::Search") {
			d$("string_to_search").value = "";
			d$("string_to_search").focus();
		}
		// clear search results
		woas._cached_body_search = [];
		woas._cached_title_search = [];
		woas._last_search = null;
		woas.pager.bucket.clear();
		if (!no_render)
			this._search_render();
	},
	// when user clicks the about link
	about: function() {
		if (!this.edit_mode)
			woas.go_to("Special::About");
	},
	_search_render: function() {
		// render search results
		if (current === "Special::Search") {
			woas._search_load();
		} else // will call _search_load() on its own
			woas.go_to("Special::Search");
	},
	// used by Special::Import
	_import_xhtml_load: function() {
		this._import_load(0);
	},
	// used by Special::ImportWSIF
	_import_wsif_load: function() {
		this._import_load(3);
	},
	
	_import_load: function(except) {
		if (!woas.config.permit_edits)
			d$("btn_import").disabled = true;
		// restore default settings - with some exceptions
		for(var i=0;i < woas.importer._settings_props.length-except;++i) {
			d$("woas_cb_import"+woas.importer._settings_props[i].substr(1)).checked =
							woas.bitfield.get(woas.config.import_settings, i);
		}
		// restore the overwrite option which covers other 2 bits
		var ovr = 0;
		if (woas.bitfield.get(woas.config.import_settings, woas.importer._OVR_ID))
			ovr += 1;
		if (woas.bitfield.get(woas.config.import_settings, woas.importer._OVR_ID+1))
			ovr += 2;
		var params = ["erase", "ignore", "overwrite", "ask"];
		// apply parameter
		d$('woas_import_'+params[ovr]).checked = true;
	},
	// click on edit icon
	edit: function() {
		woas.edit_page(current);
	},
	cancel: function() {
		if (!this.edit_mode)
			return;
		// there was some change, ask for confirm before cancelling
		if ((woas.get_raw_content() !== woas.change_buffer) ||
			(woas.trim(d$("wiki_page_title").value) !== woas.old_title)) {
			if (!confirm(woas.i18n.CANCEL_EDITING))
				return;
		}
		// we will cancel the creation of last page
		if (woas._ghost_page) {
			// we assume that the last page is the ghost page
			pages.pop();
			page_mts.pop();
			page_titles.pop();
			page_attrs.pop();
			woas._ghost_page = false;
			woas.log("Ghost page disabled"); //log:1
		}
		woas.disable_edit();
		current = woas.prev_title;
	},
	// when back button is clicked
	back: function() {
		if (this.edit_mode)
			return false;
		var p = woas.history.back();
		if (p === null)
			return false;
		woas.history._forward_browse = true;
		return woas.set_current(p, true);
	},
	// when Forward button is clicked
	forward: function() {
		//var _b_current = current,
		var p = woas.history.forward();
		if (p === null)
			return false;
		return woas.set_current(p, true)
	//	if (woas.set_current(p, true))
	//		woas.history.store(_b_current);
	},
	// when home is clicked
	home: function() {
		woas.go_to(woas.config.main_page);
	},
	ns_menu_dblclick: function() {
		if (!woas.config.dblclick_edit)
			return false;
		woas.ui.edit_ns_menu();
		return true;
	},
	edit_ns_menu: function() {
		woas.edit_page(woas.current_namespace+"::Menu");
	},
	lock: function() {
		if (woas.pager.bucket.items.length>1)
			_lock_pages(woas.pager.bucket.items);
		else
			woas.go_to("Lock::" + current);
	},
	unlock: function() {
		if (woas.pager.bucket.items.length>1)
			_unlock_pages(woas.pager.bucket.items);
		else
			woas.go_to("Unlock::" + current);
	},
	// scroll to top of page
	top: function() {
		scrollTo(0,0);
	},
	advanced: function() {
		woas.go_to("Special::Advanced");
	}
};

woas.ui._textbox_enter_event = woas.ui._textbox_enter_event_dummy;

//API1.0
woas.go_to = function(cr) {
	// won't go anywhere while editing!
	if (this.ui.edit_mode)
		return false;
	if (cr === current)
		return true;
	return this.set_current(cr, true)
};

function back_or(or_page) {
	if (!go_back())
		woas.set_current(or_page, true);
}

// when cancel is clicked
function cancel() {
	woas.log("Called deprecated function: cancel");
	woas.ui.cancel();
}

// @module help_system
woas.help_system = {
	popup_window: null,
	page_title: null,
	going_back: false,
	previous_page: [],
	_index_btn: '<'+'input class="woas_button" type="button" value="Index" onclick="help_go_index()" /'+'>',

	_mk_help_button: function(n) {
		var w = "[[Include::WoaS::Template::Button|";
		if (n)
			w += "Back|help_go_back";
		else
			w += "Close|window.close";
		w += "();]]\n";
		return w;
	},

	_help_lookup: ["Plugins", "CSS", "Aliases", "Hotkeys"],
	cPopupCode: "\nfunction get_parent_woas() {\n	if (window.opener && !window.opener.closed)\n		return window.opener.woas;\n	else return null;\n}\nwoas = {\ngo_to: function(page) { var woas = get_parent_woas();\n	if (woas !== null)\n		woas.help_system.go_to(page);\n}\n}\n// used in help popups to access index\nfunction help_go_index() {\n	var woas = get_parent_woas();\n	if (woas === null) return;\n	woas.help_system.go_to('WoaS::Help::Index');\n}\n// used in help popups to go back to previous page\nfunction help_go_back() {\n	var woas = get_parent_woas();\n	if (woas === null) return;\n	if (woas.browser.chrome || woas.browser.safari || woas.browser.opera) {\n		woas.help_system.going_back = true;\n		woas.help_system.go_to(woas.help_system.previous_page.pop());\n		return;\n	}\n	// this works for other browsers\n	scrollTo(0,0);\n	history.go(0);\n}\n",
	go_to: function(wanted_page, pi) {
//		woas.log("help_system.go_to(\""+wanted_page+"\")");	//log:0
		if (typeof pi == "undefined")
			pi = woas.page_index(wanted_page);
		var text;
		// this is a namespace
		if (pi === -1) {
			go_to(wanted_page);
			return;
		} else {
			// see if this page shall be opened in the main wiki or in the help popup
			var _pfx = "WoaS::Help::";
			if (page_titles[pi].substr(0, _pfx.length) === _pfx)
				text = woas.get__text(pi);
			else { // open in main wiki
				go_to(page_titles[pi]);
				return;
			}
		}
		if (text === null)
			return;
		// save previous page and set new
		if (this.going_back)
			this.going_back = false;
		else if (this.page_title !== null)
			this.previous_page.push( this.page_title );
		// now create the popup
		if ((this.popup_window === null) || this.popup_window.closed) {
			this.previous_page = [];
			this.popup_window = woas._customized_popup(wanted_page, this._index_btn+woas.parser.parse(
					this._mk_help_button(0)+text),
					this.cPopupCode,
				"", " class=\"woas_help_background\"");
		} else { // hotfix the page
			this.popup_window.document.title = wanted_page;
			woas.setHTMLDiv(this.popup_window.document.body, this._index_btn+woas.parser.parse(this._mk_help_button(this.previous_page.length)+text));
			this.popup_window.scrollTo(0,0);
		}
		this.page_title = wanted_page;
	}
};

function menu_dblclick() {
	if (!woas.config.dblclick_edit)
		return false;
	edit_menu();
	return true;
}

function page_dblclick() {
	if (!woas.config.dblclick_edit)
		return false;
	edit();
	return true;
}

function edit_menu() {
	woas.edit_page("::Menu");
}

/** Used by search box **/
function menu_do_search() {
	// directly use the search page if it is active
    if (current === "Special::Search") {
		d$('string_to_search').value = d$('menu_string_to_search').value;
    }
    woas.do_search(d$('menu_string_to_search').value);
}

// Used by Special::Search
// make the actual search and cache the results
function ssearch_do_search() {
	var search_string = d$("string_to_search").value;
	if ( !search_string.length )
		return;
	woas.do_search(search_string);
}

function menu_key_hook(orig_e) {
    var e;
    if (!orig_e)
        e = window.event;
    else
        e = orig_e;
	var ck = woas.browser.ie ? e.keyCode : e.which;
    if (ck == 13) {
		ff_fix_focus();
		menu_do_search();
        return false;
     }
     return orig_e;
}

//FIXME: this is entirely a bad hack
function menu_search_focus(f) {
	if (f) {
		// prevent focus on the menu search box when the search page is active
		if (current == "Special::Search") {
//		ff_fix_focus();
			d$('string_to_search').focus();
		} else {
			woas.ui.focus_textbox();
		}
	} else {
		if (current != "Special::Search")
			woas.ui.blur_textbox();
	}
}

//NOTE: this is attached to onkeydown of menu's search box, so you can't use 'this'
woas.do_search = function(str, noclear) {
	// clear previous search results
	if (!noclear)
		woas.ui.clear_search(true);

	woas.progress_init("Searching");
	// reset result pages
	woas.pager.bucket.clear();

	// cache new search results
	woas._cache_search( str );
	woas.progress_finish();

	// refresh the search page, or go to it if we are not
	woas.ui._search_render();
};

// Used by Special::Options page
function save_options() {
	if (!woas.config.permit_edits) {
		alert(woas.i18n.READ_ONLY);
		return false;
	}
	woas.cfg_commit();
	woas.set_current("Special::Advanced", true);
}

function ro_woas() {
	if (!woas.config.permit_edits) {
		alert(woas.i18n.WRITE_PROTECTED);
		return false;
	}
	if (confirm(woas.i18n.CONFIRM_READ_ONLY)) {
		woas.config.permit_edits = false;
		woas.cfg_commit();
		woas.set_current("Special::Advanced", true);
	}
}

// Used by Special::Lock
function lock_page(page) {
	var pwd = d$("pw1").value;
	if (!pwd.length) {
		d$("pw1").focus();
		return;
	}
	if (pwd !== d$("pw2").value) {
		d$("pw2").focus();
		return;
	}
	var pi = woas.page_index(page);
	woas.AES.setKey(pwd);
	woas._finalize_lock(pi);
}

// import wiki from external file
function import_wiki() {
	if (!woas.config.permit_edits) {
		alert(woas.i18n.READ_ONLY);
		return false;
	}
	woas.import_wiki();
	woas.refresh_menu_area();
}

function set_key() {
	woas._set_password();
}

// below function is used by Special::Lock

var _pw_q_lock = false;

function pw_quality() {

	if (_pw_q_lock)
		return;
		
	_pw_q_lock = true;

// used to get a red-to-green color tone
function _hex_col(tone) {
	var s=Math.floor(tone).toString(16);
	if (s.length==1)
		return "0"+s;
	return s;
}

	// original code from http://lxr.mozilla.org/seamonkey/source/security/manager/pki/resources/content/password.js
	var pw=d$('pw1').value;

	//length of the password
	var pwlength=pw.length;
	
	if (pwlength!==0) {

	//use of numbers in the password
	  var numnumeric = pw.match(/[0-9]/g);
	  var numeric=(numnumeric!==null)?numnumeric.length/pwlength:0;

	//use of symbols in the password
	  var symbols = pw.match(/\W/g);
	  var numsymbols= (symbols!==null)?symbols.length/pwlength:0;

	//use of uppercase in the password
	  var numupper = pw.match(/[^A-Z]/g);
	  var upper=numupper!==null?numupper.length/pwlength:0;
	// end of modified code from Mozilla
	
	var numlower = pw.match(/[^a-z]/g);
	var lower = numlower!==null?numlower.length/pwlength:0;
	
	var u_lo = upper+lower;
	  
	// 80% of security defined by length (at least 16, best 22 chars), 10% by symbols, 5% by numeric presence and 5% by upper case presence
	var pwstrength = ((pwlength/18) * 65) + (numsymbols * 10 + u_lo*20 + numeric*5);
	
	var repco = woas.split_bytes(pw).toUnique().length/pwlength;
	if (repco < 0.8)
		pwstrength *= (repco+0.2);
//		woas.log("pwstrength = "+(pwstrength/100).toFixed(2)+", repco = "+repco);	// log:1
	} else
		pwstrength = 0;
  
	if (pwstrength>100)
		color = "#00FF00";
	else
		color = "#" + _hex_col((100-pwstrength)*255/100) + _hex_col((pwstrength*255)/100) + "00";
  
	d$("pw1").style.backgroundColor = color;
	woas.setHTMLDiv(d$("txtBits"), "Key size: "+(pwlength*8).toString() + " bits");
	
	_pw_q_lock = false;
}

// used by embedded file show page
function show_full_file(pi) {
	var text = woas.get__text(pi);
	if (text===null)
		return;
	// put WoaS in loading mode
	woas.progress_init("Loading full file");
	// clear the partial display and put in the whole file content
	woas.setHTML(d$('_part_display'), '');
	woas.setHTML(d$('woas_file_ct'), woas.xhtml_encode(woas.base64.decode(text)));
	// finished loading the file
	woas.progress_finish();
}

function query_export_file(cr) {
	var fn = cr.substr(cr.indexOf("::")+2);
	if (confirm(woas.i18n.CONFIRM_EXPORT.sprintf(cr)+"\n\n"+woas.ROOT_DIRECTORY+fn))
		woas.export_file(cr, woas.ROOT_DIRECTORY+fn);
}

function query_export_image(cr) {
	var img_name = cr.substr(cr.indexOf("::")+2);
	if (confirm(woas.i18n.CONFIRM_EXPORT.sprintf(img_name)+"\n\n"+woas.ROOT_DIRECTORY+img_name))
		woas.export_image(cr, woas.ROOT_DIRECTORY+img_name);
}

function query_delete_file(cr) {
	if (!confirm(woas.i18n.CONFIRM_DELETE.sprintf(cr)))
		return;
	// do not check for plugin deletion here
	woas.delete_page(cr);
	back_or(woas.config.main_page);
}

// delayed function called after page loads and runs the script tag
function _img_properties_show(mime, tot_len, enc_len, mts) {
	var img=d$('woas_img_tag');
	woas.setHTML(d$('woas_img_desc'),
		woas.i18n.MIME_TYPE+": "+mime+"<"+"br /"+
		">"+woas.i18n.FILE_SIZE+": about "+_convert_bytes(((tot_len-enc_len)*3)/4)+
		woas.i18n.B64_REQ.sprintf(_convert_bytes(tot_len))+
	"<"+"br />"+woas.last_modified(mts)+
	"<"+"br />"+woas.i18n.WIDTH+": "+img.width+"px<"+"br />"+woas.i18n.HEIGHT+": "+img.height+"px");
}

function query_delete_image(cr) {
	if (!confirm(woas.i18n.CONFIRM_DELETE_IMAGE.sprintf(cr)))
		return;
	// do not check for plugin deletion here
	woas.delete_page(cr);
	back_or(woas.config.main_page);
}

// triggered by UI graphic button
function page_print() {
	woas._customized_popup(current, woas.getHTMLDiv(d$("woas_wiki_area")),
			'function go_to(page) { alert("'+woas.js_encode(woas.i18n.PRINT_MODE_WARN)+'");}');
}

woas._customized_popup = function(page_title, page_body, additional_js, additional_css, body_extra) {
	var css_payload = "";
	if (woas.browser.ie && !woas.browser.ie8) {
		if (woas.browser.ie6)
			css_payload = "div.woas_toc { align: center;}";
		else
			css_payload = "div.woas_toc { position: relative; left:25%; right: 25%;}";
	} else
		css_payload = "div.woas_toc { margin: 0 auto;}\n";
	
	if (additional_js.length)
		additional_js = woas.raw_js(additional_js);
	// create the popup
	return woas.popup(
		"print_popup",
		Math.ceil(screen.width*0.75),
		Math.ceil(screen.height*0.75),
		",status=yes,menubar=yes,resizable=yes,scrollbars=yes",
		// head
		"<"+"title>" + page_title + "<"+"/title>" + "<"+"style type=\"text/css\">"
		+ css_payload + woas.css.get() + additional_css +
		"<"+"/sty" + "le>" + additional_js,
		page_body,
		body_extra
	);
};

// below functions used by Special::Export

woas.export_wiki_wsif = function () {
	var path, author, single_wsif, inline_wsif;
	try {
		path = d$("woas_ep_wsif").value;
		author = this.trim(d$("woas_ep_author").value);
		single_wsif = d$("woas_cb_single_wsif").checked ? true : false;
		inline_wsif = d$("woas_cb_inline_wsif").checked ? true : false;
	} catch (e) { this.crash(e); return false; }
	
	var done = this._native_wsif_save(path, this.wsif.DEFAULT_INDEX, false, single_wsif, inline_wsif, author, false);

	this.alert(this.i18n.EXPORT_OK.sprintf(done, this.wsif.expected_pages));
	return true;
};

// workaround to get full file path on FF3
// by Chris
function ff3_getPath(fileBrowser) {
	try {
		netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
	} catch (e) {
	    alert('Unable to access local files due to browser security settings. '
	    +'To overcome this, follow these steps: (1) Enter "about:config" in the URL field; '+ 
	    '(2) Right click and select New->Boolean; (3) Enter "signed.applets.codebase_principal_support" '+
	     '(without the quotes) as a new preference name; (4) Click OK and try loading the file'+
	     ' again.');
	    return false;
	}
	var fileName=fileBrowser.value;
	return fileName;
}

// create a centered popup given some options
woas.popup = function(name,fw,fh,extra,head,body, body_extra) {
	if (typeof body_extra == "undefined")
		body_extra = "";
	var hpos=Math.ceil((screen.width-fw)/2);
	var vpos=Math.ceil((screen.height-fh)/2);
	var wnd = window.open("about:blank",name,"width="+fw+",height="+fh+		
	",left="+hpos+",top="+vpos+extra);
	wnd.focus();
	wnd.document.writeln(this.DOCTYPE+"<"+"html><"+"head>"+head+
						"<"+"/head><"+"body"+body_extra+">"+
						body+"<"+"/body></"+"html>\n");
	wnd.document.close();
	return wnd;
};

// tell user how much work was already done
woas.progress_status = function (ratio) {
	// no progress indicators in debug mode
	if (this.config.debug_mode) return;
	this.setHTML(d$("woas_wait_text"), this._progress_section + "\n" +
				Math.ceil(ratio*100)+"% done");
};

// used to debug progress indicators
woas._progress_section = false;

// reset progress indicator
woas.progress_init = function(section) {
	if (this._progress_section !== false) {
		this.crash("Progress indicator already started for "+this._progress_section+
					", will not start a new one for "+section);
		return;
	}
	this._progress_section = section;
	if (typeof section == "undefined")
		section = "";
	else section = "\n" + section;
	// no progress indicators in debug mode
	if (this.config.debug_mode) return;
	this.setHTML(d$("woas_wait_text"), section);
	document.body.style.cursor = "wait";
	// put in busy mode and block interaction for a while
	d$.show("loading_overlay");
	d$("loading_overlay").focus();
};

woas.progress_finish = function(section) {
	if (this._progress_section === false) {
		this.crash("Cannot finish an unexisting progress indicator section");
		return;
	}
	// no progress indicators in debug mode
	if (!this.config.debug_mode) {
		document.body.style.cursor = "auto";
		this.setHTML(d$("woas_wait_text"), this.i18n.LOADING);
		// hide the progress area
		d$.hide("loading_overlay");
	}
	this._progress_section = false;
};

function search_focus(focused) {
	if (focused) {
		woas.ui._textbox_enter_event = ssearch_do_search;
		woas.ui.focus_textbox();
	} else {
		woas.ui.blur_textbox();
		ff_fix_focus();
	}
}

woas._hl_marker = _random_string(10)+":%d:";

woas._hl_marker_rx = new RegExp(woas._hl_marker+":(\\d+):", "g");

// display search results
woas._search_load = function() {
	woas.log("called _search_load()");
	var P = {body: ""};
	if (this._last_search === null) {
//		woas.log("No search done, returning blank");	//log:0
	} else {
		// proceed to parsing if there are matching pages
		if (this._cached_title_search.length + this._cached_body_search.length !== 0) {
		
			// (1) prepare the title results
			for(var i=0,it=this._cached_title_search.length;i<it;++i) {
				P.body += "* [["+ this._cached_title_search[i] + "]]\n";
				woas.pager.bucket.add(this._cached_title_search[i]);
			}
			
			// (2) parse the body snippets
			for(var i=0,it=this._cached_body_search.length;i<it;++i) {
				P.body += "* [[" + this._cached_body_search[i].title + "]]: found " + this._hl_marker+":"+i+":";
				woas.pager.bucket.add(this._cached_body_search[i].title);
			}

			P.body = 'Results for <'+'strong class="woas_search_highlight">' + woas.xhtml_encode(woas._last_search) + "<"+"/strong>\n" + P.body;
		} else
			P.body = "/No results found for *"+woas.xhtml_encode(woas._last_search)+"*/";

	}

	// position cursor back in search box
	d$("string_to_search").focus();
	
	if (P.body.length) {
		// parse results before applying search terms highlighting
		woas.parser.syntax_parse( P, [] );
		
		P.body = P.body.replace(this._hl_marker_rx, function(str, i) {
			var r="",count=0;
			for(var a=0,at=woas._cached_body_search[i].matches.length;a<at;++a) {
				r += "<"+"pre class=\"woas_nowiki woas_search_results\">" +
						// apply highlighting
						woas._cached_body_search[i].matches[a].replace(woas._reLastSearch, function(str, $1) {
							++count;
								return '<'+'span class="woas_search_highlight">'+$1+'<'+'/span>';
						})+"\n<"+"/pre>";
			}
			return " <"+"strong>"+count+"<"+"/strong> times: "+r;
		});
	}
	
	// finally output XHTML content
	woas.setHTMLDiv(d$('woas_search_results'), P.body);
};

var _servm_shown = false;

function _servm_alert() {
	if (woas._server_mode) {
		// show the message only once
		if (!_servm_shown) {
			woas.alert(woas.i18n.SERVER_MODE);
			_servm_shown = true;
		}
	}
}

woas.update_nav_icons = function(page) {
	this.menu_display("back", this.history.has_backstack());
	this.menu_display("forward", this.history.has_forstack());
	this.menu_display("advanced", (page != "Special::Advanced"));
	this.menu_display("edit", this.edit_allowed(page));
	this.update_lock_icons(page);
};

woas.update_lock_icons = function(page) {
	var cyphered, can_lock, can_unlock;
	if (woas.pager.bucket.items.length < 2) {
		var pi = this.page_index(page);
		if (pi==-1) {
			can_lock = can_unlock = false;
			cyphered = false;
		} else {
			can_unlock = cyphered = this.is__encrypted(pi);
			can_lock = !can_unlock && this.config.permit_edits;
		}
	} else {
		can_lock = can_unlock = (woas.pager.bucket.items.length>0);
		cyphered = false;
	}
	
	// update the encryption icons accordingly
	this.menu_display("lock", !woas.ui.edit_mode && can_lock);
	this.menu_display("unlock", !woas.ui.edit_mode && can_unlock);
	// we can always input decryption keys by clicking the setkey icon
	//this.menu_display("setkey", cyphered);
	var cls;
	if (cyphered || (page.indexOf("Locked::")==0))
		cls = "woas_text_area locked";
	else
		cls = "woas_text_area";
	d$("woas_wiki_area").className = cls;
};

// when the page is resized
woas._onresize = function() {
	var we = d$("woas_editor");
	we.style.width = window.innerWidth - 30 + "px";
	we.style.height = window.innerHeight - 150 + "px";
};

if (!woas.browser.ie)
	window.onresize = woas._onresize;

woas._set_debug = function(status) {
	if (status) {
		// activate debug panel
		d$.show_ni("woas_debug_panel");
		d$.show("woas_debug_log");
		// hide the progress area
		d$.hide("loading_overlay");
	} else {
		d$.hide_ni("woas_debug_panel");
		d$.hide("woas_debug_console");
	}
};

woas.refresh_menu_area = function() {
	var tmp = this.current_namespace;
 	this.current_namespace = this.parser.marker;
	this._add_namespace_menu(tmp);
	var menu = this.get_text("::Menu");
	if (menu == null)
		this.setHTMLDiv(d$("woas_menu_area"), "");
	else {
		this.parser._parsing_menu = true;
		this.setHTMLDiv(d$("woas_menu_area"), this.parser.parse(menu, false, this.js_mode("::Menu")));
		this.parser._parsing_menu = false;
		this.scripting.clear("menu");
		this.scripting.activate("menu");
	}
};

woas._gen_display = function(id, visible, prefix) {
	if (visible)
		d$.show(prefix+"_"+id);
	else
		d$.hide(prefix+"_"+id);
};

woas.img_display = function(id, visible) {
	if (!this.browser.ie || this.browser.ie8) {
		this._gen_display(id, visible, "img");
		this._gen_display(id, !visible, "alt");
	} else {
		this._gen_display(id, !visible, "img");
		this._gen_display(id, visible, "alt");
	}
};

woas.menu_display = function(id, visible) {
	this._gen_display(id, visible, "menu");
//	log("menu_"+id+" is "+d$("menu_"+id).style.display);
};

woas.refresh_mts = function(mts) {
	// generate the last modified string to append
	if (mts) {
		this.setHTMLDiv(d$("woas_mts"), this.last_modified(mts));
		d$.show("woas_mts");
	} else
		d$.hide("woas_mts");
};

woas._set_title = function (new_title) {
	this.setHTMLDiv(d$("woas_title"), this.create_breadcrumb(new_title));
	document.title = new_title;
};

// function which hooks all messages shown by WoaS
// can be fed with multiple messages to show consecutively
woas.alert = function() {
	for(var i=0,l=arguments.length;i < l;++i) {
		alert("WoaS: "+arguments[i]);
	}
};

// same as above, but for unhandled errors
woas.crash = function() {
	for(var i=0,l=arguments.length;i < l;++i) {
		alert("WoaS Unhandled error\n----\n"+arguments[i]);
	}
};

// called from Special::Lock page
function _lock_page() {
	// do not call if not on a page locking context
	if (current.indexOf("Lock::")!==0)
		return;
	var page = current.substring(6);

	d$("btn_lock").value = "Lock "+page;
	d$("pw1").focus();
	//TODO: check for other browsers too
	if (woas.browser.firefox)
		d$("btn_lock").setAttribute("onclick", "lock_page('"+woas.js_encode(page)+"')");
	else
		d$("btn_lock").onclick = woas._make_delta_func('lock_page', "'"+woas.js_encode(page)+"'");
}

function _woas_new_plugin() {
	var title = woas._prompt_title("Please enter plugin name", "Myplugin");
	if (title === null)
		return;
	var def_text;
	// provide special include page support
	// --UNSUPPORTED FEATURE--
	if (title.charAt(0) === '@') {
		def_text = "plugins/"+title.substr(1)+".js\n";
//		title = title.substr(1);
	} else {
		def_text = "/* "+title+" plugin */\n";
	}
	woas._create_page_direct("WoaS::Plugins", title, false, def_text);
	// now we will be editing the plugin code
}

// get file URL from input XHTML element
// this might not work on some browsers
// not to be called for Mozilla-based browsers
woas.get_input_file_url = function() {
	var r = false;
	if (this.browser.opera || this.browser.webkit) {
		// ask user for path, since browser do not allow us to see where file really is
		r = d$("filename_").value;
		r = prompt(this.i18n.ALT_BROWSER_INPUT.sprintf(this.basename(r)), this.ROOT_DIRECTORY);
		if ((r === null) || !r.length)
			r = false;
		else
			this._last_filename = r;
	} else { // we have requested a direct read of the file from the input object
		r = d$("filename_").value;
		if (!r.length)
			r = false;
	}
	if (r === false)
		this.alert(this.i18n.FILE_SELECT_ERR);
	return r;
};

/*
woas.css.ff2 (string:valid CSS): css added if browser == ff2 when !raw 
woas.css.set(css, raw)
  css (string:valid CSS): the raw css to be set; replaces old css
  raw (boolean, optional): if true browser fixes will not be applied to css
woas.css.get(): returns currently set CSS (string:valid CSS)
*/
//FIXME: could be part of woas.ui object
woas.css = {
	FF2: "\n.woas_nowiki { white-space: -moz-pre-wrap !important; }\n",
	IE: "\n.woas_nowiki { word-wrap: break-word !important; }\n",
	OPERA: "\n.woas_nowiki { white-space: -o-pre-wrap !important; }\n",
	
	// TODO: replace with factory function for just this browser
	set: function(css, raw) {
		raw = raw || false;
		/*
		This object could become much better in the future, grabbing content
		from appropriate sources, or filtering WoaS::CSS (whatever) to match
		the current browser ... this need only be done once on loading page,
		with a callback function for CSS editing (e.g. woas.css.load and/or
		woas.css.merge, etc.). Note that this change does not affect efficiency
		much but now we can completely change the way this works (over time)
		without having to modify other code. This is generally applicable
		with OOP design concepts. The code is therefore much less fragile
		and many programmers can work on it with changes tending to be much
		more confined to the object they are modifying.
		*/
		// add some browser-specific wrapping fixes
		if (!raw) {
			if (woas.browser.firefox2)
				// fixes are added first so they can be overridden
				// (although they have an !important property attribute)
				css = this.FF2 + css;
			else if (woas.browser.trident)
				css = this.IE + css;
			else if (woas.browser.presto)
				css = this.OPERA + css;
		}
		if (woas.browser.ie)
			woas.dom._cache.stylesheet.cssText = css;
		else {
			if (woas.browser.chrome || woas.browser.safari)
				woas.dom._cache.stylesheet.innerText = css;
			else
				woas.dom._cache.stylesheet.innerHTML = css;
		}
	},
	
	// Not used/needed in public API; can't easily fix this with current code.
	// Can't see this being a problem though.
	get: function() {
		if (woas.browser.ie)
			return woas.dom._cache.stylesheet.cssText;
		// on Chrome/Safari innerHTML contains br tags
		if (woas.browser.chrome || woas.browser.safari)
			return woas.dom._cache.stylesheet.innerText;
		return woas.dom._cache.stylesheet.innerHTML;
	}
};

/*** src/editor.js ***/
// @module ui.editor
// this sub-module shall contain the whole editor code
woas.ui.editor = {
	_insert_ruler: function() {
		TagThis("\n----\n", "");
	}
};

woas.wiki_buttons_display = function (v) {
	d$('wiki_format_buttons').style.display = v ? 'block' : 'none';
	d$('wiki_format_buttons').style.visibility = v ? 'visible' : 'hidden';
};

woas.html_buttons_display = function (v) {
	d$('html_format_buttons').style.display = v ? 'block' : 'none';
	d$('html_format_buttons').style.visibility = v ? 'visible' : 'hidden';
};

// class for managing textarea selection - by pr0xy
function TextAreaSelectionHelper(obj) {
	this.target=obj;
	this.target.carretHandler=this; // ?
	this.target.onchange=_textareaSaver;
	this.target.onclick=_textareaSaver;
	this.target.onkeyup=_textareaSaver;
	this.target.onfocus=_textareaSaver;
	if(!document.selection)
		this.target.onSelect=_textareaSaver; // ?
 
	this.start=-1;
	this.end=-1;
	this.scroll=-1;
	this.iesel=null;
}

TextAreaSelectionHelper.prototype.getSelectedText=function() {
	if (this.iesel)
		return this.iesel.text;
	// Fixes a problem in FF3 where the selection was not being stored in this.start and this.end when selecting multilines
	this.start = d$("woas_editor").selectionStart;
	this.end = d$("woas_editor").selectionEnd;
	return ((this.start>=0)&&(this.end>this.start))? this.target.value.substring(this.start,this.end): "";
};

TextAreaSelectionHelper.prototype.setSelectedText=function(text, secondtag) {
	if(this.iesel) {
	if(typeof(secondtag)=="string") {
	  var l=this.iesel.text.length;
		 this.iesel.text=text+this.iesel.text+secondtag;
	  this.iesel.moveEnd("character", -secondtag.length);
	   this.iesel.moveStart("character", -l);   
	} else {
	  this.iesel.text=text;
	}
	this.iesel.select();
 } else if(this.start>=0&&this.end>=this.start) {
    var left=this.target.value.substring(0,this.start);
    var right=this.target.value.substr(this.end);
 var scont=this.target.value.substring(this.start, this.end);
 if(typeof(secondtag)=="string") {
   this.target.value=left+text+scont+secondtag+right;
   this.end=this.target.selectionEnd=this.start+text.length+scont.length;
   this.start=this.target.selectionStart=this.start+text.length;    
 } else {
      this.target.value=left+text+right;
   this.end=this.target.selectionEnd=this.start+text.length;
   this.start=this.target.selectionStart=this.start+text.length;
 }
 this.target.scrollTop=this.scroll;
 this.target.focus();
 } else {
   this.target.value+=text + ((typeof(secondtag)=="string")? secondtag: "");
if(this.scroll>=0) this.target.scrollTop=this.scroll;
 }
};

TextAreaSelectionHelper.prototype.getText=function() {
	return this.target.value;
};

TextAreaSelectionHelper.prototype.setText=function(text) {
	this.target.value=text;
};

function _textareaSaver() {
	if (document.selection) {
		this.carretHandler.iesel = document.selection.createRange().duplicate();
	} else if(typeof(this.selectionStart)!="undefined") {
		this.carretHandler.start=this.selectionStart;
		this.carretHandler.end=this.selectionEnd;
		this.carretHandler.scroll=this.scrollTop;
	} else
		this.carretHandler.start=this.carretHandler.end = -1;
}

function DivTagThis(align) {
	TagThis('<'+'div align="'+align+'">', '<'+'/div>');
}

function TagThis(starttag, endtag){
	woas._editor.setSelectedText(starttag, endtag);
}

function FullTagThis(tag){
	woas._editor.setSelectedText('<'+tag+'>','<'+'/'+tag+'>');
}

function setUrl(starttag,centertag,endtag) {
	var url=prompt('Link:','http://');
	if (url===null) return;
	var comm=prompt('Link text:','');
	if (comm===null) return;
		woas._editor.setSelectedText(starttag+woas.js_encode(url)+centertag,comm+endtag);
}

function setWikiImage() {
	setImage('[[Include::Image::',']]');
}

function setHTMLImage() {
	setImage('<'+"img src='","' /"+">");
}

function setWikiUrl() {
	setUrl('[[','|',']]');
}

function setWikiIUrl() {
	var url=prompt('Wiki page to link to:','');
	if (url===null) return;
	var comm=prompt('Link text:', url);
	if (comm===null) return;
	if (comm == url)
		woas._editor.setSelectedText('[['+url+']]');
	else
		woas._editor.setSelectedText('[['+url+'|',comm+']]');
}

function setHTMLUrl() {
	setUrl('<'+'a href="','" target="_blank">','<'+'/a>');
}

function setImage(starttag,endtag) {
	var pic=prompt('Image:','');
	if (pic!==null)
		woas._editor.setSelectedText(starttag,woas.js_encode(pic)+endtag);
}

function setTag() {
        var tag=prompt('Set tag:','');
	if (tag!==null)
	woas._editor.setSelectedText("[[Tag::",tag+"]]");
}


/* ]]> */ </script></head><body class="woas_background" id="body" style="cursor: auto;" onload="woas._on_load()" onunload="woas._on_unload()">
<div style="display: inline; visibility: visible;" id="loading_overlay"><noscript><h1>If you are seeing this text, your browser is not javascript-enabled.</h1></noscript><div id="woas_wait_text">Loading Wiki on a Stick...</div></div>
<div style="display: none; visibility: hidden;" id="woas_pwd_mask">
<div style="visibility: visible;" id="woas_pwd_query">
<form id="stealthpwd" action="" onsubmit="woas._password_ok(); return false">
<h3>Enter a decryption password</h3>
<p><input name="woas_password" id="woas_password" size="16" type="password" /></p>
<p class="woas_password_desc">Password will be used next time you attempt to access an encrypted page, and then kept or removed second the AES key caching option you have chosen.</p>
<p><input value="OK" type="submit" />&nbsp;<input value="Cancel" onclick="woas._password_cancel()" class="woas_button" type="button" /></p>
</form>
</div>
</div>
<div class="woas_background" id="woas_wiki_header" style="position: fixed;">
<table cellspacing="0" width="100%">
<tbody><tr>
<td style="width: 35px;" id="woas_logo"><img style="display: inline; visibility: visible;" id="img_logo" alt="WoaS Logo" src="%2FAAAAAXNSR0IArs4c6QAAAAJiS0dEAP%2BHj8y%2FAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH2gEcDzUY4t9JowAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAI7SURBVEjHtdVPSFRRFAbw33ujljETWhaGo9YiCGoVuHDTIggE2xRBbgeEoFWQFARBq3ZCELQKgqJtbWtTEAitgqBNCZJFGGb%2B18Hxz20xr3HSmXEU%2Bt7ivnvf%2B757z3feOydSAZNh2QrW0IAm%2Bx2LVMS25e9h0UbFF5u1aI1qCvwMs9ZVRyStK6oq8D3M2xn7HdYSVRAYC3n1ocHRslDi4vCtbjprpspmcTH2BbtBwddQJjATZu0Wi36FvwFZqOk861atbUttvDku1SAHeUsKFb6MueQM8c%2BwUcOuJatVnxYDb8hX3XtFoWZoxZM3LFkpW0wlfmxY29HIvNnQEsV5fQql62IyVqO%2FknPegNtgFfG6wyZ80GtaQRrjcnpdN5eQhvTrNwaG5Tx3S0%2BSH%2BIga9SItA8mZTGs21MZTxKBnMfuJLOsLzLOupL4RJySNeadGyWBT645adAbMO6xnCHvwUNcMmg0cYy4Ubc30vp9NaG7FG1TYueQHve9sAjSBr10xj3QiLhZp1F96PRWJ854ZsIjF8CK07LeYQ4PfJRyCuzTGhEfkJVyAeeMyOKmTy5bkAODbhsw4ZyrGDekz2t3kSnWg5nwWbAXHHcsIm6NDu2J%2FrfMxrRJ7UGgffNvPBQd2TU9UyrzMZyIDu6K3qRja13o0Fw3PaWrrKiWbmbCDwt17d7lSFSlsYyG3zukNKNjS3fa0md%2BhUnzVRPXXqFDVmiZU2HOouV%2Fjn1QRntUV3PdxHRYRUpb5H%2FiD%2FUerIBA%2BEx5AAAAAElFTkSuQmCC" /></td>
<td><span id="woas_title"></span></td>
<td align="right">
<div id="menu_back" style="display: inline; cursor: pointer; visibility: visible;"><a title="Back" onclick="woas.ui.back()"><img id="img_back" style="display: inline; visibility: visible;" alt="Back" src="" /><span id="alt_back" style="display: none; visibility: hidden;">&nbsp;<strong>[Back]</strong>&nbsp;</span></a></div>
<div id="menu_forward" style="display: none; cursor: pointer; visibility: hidden;"><a title="Forward" onclick="woas.ui.forward()"><img id="img_forward" style="display: inline; visibility: visible;" alt="Forward" src="" /><span id="alt_forward" style="display: none; visibility: hidden;">&nbsp;<strong>[Forward]</strong>&nbsp;</span></a></div>
<div id="menu_advanced" style="display: inline; cursor: pointer; visibility: visible;"><a title="Advanced" onclick="woas.ui.advanced()"><img id="img_advanced" style="display: inline; visibility: visible;" alt="Advanced" src="" /><span id="alt_advanced" style="display: none; visibility: hidden;">&nbsp;<strong>[Advanced]</strong>&nbsp;</span></a></div>
<div id="menu_home" style="display: inline; cursor: pointer; visibility: visible;"><a id="woas_home_hl" title="Main Page" onclick="woas.ui.home()"><img id="img_home" style="display: inline; visibility: visible;" alt="Main Page" src="" /><span id="alt_home" style="display: none; visibility: hidden;">&nbsp;<strong>[Home]</strong>&nbsp;</span></a></div>
<div id="menu_unlock" style="display: none; cursor: pointer; visibility: hidden;"><a title="Unlock" onclick="woas.ui.unlock()"><img id="img_lock" style="display: inline; visibility: visible;" alt="Unlock" src="%2FwD%2FAP%2BgvaeTAAAEnUlEQVR42o2WX2wUVRTGf3NnZ7a7tkvTdA1rlxSWthgwEpoawh9jS8SHxofqAyaGBzBBE15IBLTxwfgCGBITfZAXk%2FYBjDE09QGJpqKFGBKiDYkuVChd7KbbbbtLy3bb2dk%2Fs3N96M52t63ASU5m5t7c853zne%2FeOwoV9vDhwxpWWSgUypVelYphWfKnmnACrxd8z549rwB2yYslfwuoB9zAayWgXYBrXQQneKU3NzfvcrLs7%2B%2BXsVhMTk1NyVu3bsmK7N8EZCqVcr4PlUDXVlBpBw4ceDEajd7u7e0tJpNJDh48SDqdJpVK4ff7iUQi9Pf3A1wBWFpa4s6dOwDfA92rQdYAzM3NvQRw%2BvRp9erVq1YwGGT79u3s2LGDrVu3Eg6H87t376avr6%2B8ZnZ2lgcPHgAMAi2V%2FaribXp6WllcXLw4MTHByMgIR44ccW3YsOFDr9c76vP54vF4vKOnp6cvGo3S1NRUlVhrayvAp6vEsLYCALd7pUqPx3O%2FpaVl9OjRoxPnzp27%2FH9qOX78OMAMMF2psKoKxsfHBYBpmuUxr9c729raagQCAftJcrxw4QKACeQrx8sA4XBYDAwM1K5eaBiGb3h4uOn69es2z2bFdQG%2B%2FOiDd4bvz%2FQBDA4OkkgknAb%2BtjrCsWPHqK1dyUXXdS5dusThw4cvAreBfxyaFGeDhUIhMxUfJT8%2Fibn4iHzGIJtZYPFxCjOTAUDTNPQaN8Klorlr2NXTSywWI5FI0N7eDvAV8DUQKW3O6h4ouTS59AxGIkrWWCLzOMlcMsGSsQQSPJ4adK8HVRVo6spJUVdXx82bN9m3b98J4LsSwFoV2baNLC5TKG2wFXtZcxKEEKAoKELBtiWvn%2FqBzz45iRCCuro6VFV1wmwCtHVVBBIpJUiJlEViMynGJmYxM1kE0FBfy6aNcPZKnEgkghCCTIm%2BxsZGhoeH6erqugy8CvwJ5KopEipCCBShIIQk8Hw9HpEjs7CIRCBqdHq%2FvceNGzcoFAqMj49jWRaKoqDrOps3b2ZkZISOjo7fgZ3AXREKhbIrHBWxihZWvoCVL%2FDocZrJxBJT81kSCxne%2FfxXzp45g5TLlWqaRltbG21tbWzZsoX6%2Bnr8fj%2Fnz58H%2BAtocJUUlF0mSEFVVFSXC6G6aPR5EVkPGbeNXVJ3Z1cXhmGgKArbtm1D1%2FXl6hWl%2FOzs7HRS3ljdA9tCFjIUcovkc2mi8QTzyXlMw0RzucoBHDdNk0AgAEA0Gi2PO6BA%2FaoeKEhVQwg3Lk0nuLGBWlVimu4qwTmBQqEQwBeAbG5uPjU5OYmiKOTz%2Bf857Io2kiKyWMAqFLByuVJPLGTRAuCXoaEyHQCH3mg%2FeeLtnaecHW1ZFkNDQ870QtU9%2B%2FM3HzPx7zjZhSRZM0sulyWfzVKwiggUajw6g6Murl27hmEYaJpGMBgEIBaLoes6Y2Nj7N%2B%2FH%2BA94McywMt%2B%2FYW%2Fk%2FmpZznN9u7dy8DAALa9cv6Fw2GklHR3dwP0Aj8BdysrUAAV0EvP1X8Slfacz%2BeLp9Pp9ebeB%2F4A7gE55SnJPmneBTQAAaDO4bx06cwDFsB%2F1pf2UYdfB6cAAAAASUVORK5CYII%3D" /><span id="alt_unlock" style="display: none; visibility: hidden;">&nbsp;<strong>[Unlock]</strong>&nbsp;</span></a></div>
<div id="menu_lock" style="display: inline; cursor: pointer; visibility: visible;"><a title="Lock" onclick="woas.ui.lock()"><img id="img_unlock" style="display: inline; visibility: visible;" alt="Lock" src="%2Br5wAAAAlwSFlzAAALEwAACxMBAJqcGAAAAARnQU1BAACxjwv8YQUAAANZSURBVHja3VTPT1NZGD3vvZYWGGqVNgKyEBZqwsRYtRpjJpkdMbNk5YrMZjYQF27c%2Bxe4MCxcIJmdyRAjGxMX%2FohKUGMgMAt%2BTCJ0CtqR2tLS9%2Fp%2B3eu5r8UEZphS48qbnL57b9895%2FvO970LfK%2FjKjFJlIhHxH0i9a3Ib%2Fb396%2BPj4%2FLjY0NOTMzIycmJvxEImHyv1%2BbJTP2rG8PDw9fn5ycjPX19aFYLCIWi6Gnp0cbGBgI5%2FP5XzKZjMb3nn1N5FfS6bRZKBTk%2FPx8ZWho6C337GQymR0ZGbHn5ubk1NSUHBwcLNctbHo8YHRycXFRplKpP7ieIS4TP8Xj8eejo6OmsmtsbMzh3r2m2elxMZfLyenp6QqXK8TPRCuhLEn39vZm19bWpKoN1wsH5dV3Jp2dnZFKpYJyuawIbGKeqBJq%2FSabzYrNzU10d3Wp15MHFQjtTJaWlm6xe4bry8eEl2zVb3UfO3rt71wRoegPePniBeUEWiPhoyFDlwQOd7SjI9EN27ZRyr9HV4eB5Wzx3rYbdJyl7RGMEXHCJ3KEW1h5AiE0eJ6A8F3OHVjFf%2Fj0gtSE70G4Nnzbgl%2B18ObhXfz2%2B7riOkvMhvYIlOr4MjSyWPlVlHKr8Cng2xXYTpWJCEgpKcw9x4S3XYBjbkEEssHo2lWD%2FYYQPiSjrC3okFarOnQdmq5B09QGaTQ1N0j4xRRjVw32HzKIlD9YWPgTy6vrsMxqEJlQbdYWxYnjx5CIePBdZiPkrtMNBTSdUdWjPX%2FpAk6fs%2BDRJk9lRZuEWw1sK7ERAuo9VW2cAS1SZJ7jYPbt7P4ZtNTIQ0aoOQHJUwa9NUJhnLuYxunUKbhsSZ%2BiyjqpCuxWsJ3jnPZE2w%2FzVKYJAeEFNrhOBXOzK%2FtmEIcXNITREm22BjqkEWYdIjh74Qx%2BPHOSNbAhpAgKr%2Fz3XQvlDwZaolG4bqTJGvhsU6hWdWFuleHwg1K9L%2Bqtqz4yzzah0cJo2yGU88Vdx40G9O3p%2FrbLbRo9%2FpiBVSrALH9ClVCdJDybNVDZaAxCh7W9haevlvH6nfmUZ3mv4K%2F%2FZaf6RT7uoHbhHRRPiBvEeeBfXftfGjhC9KD26YcbWlq7xz4SWeJDI4EdEUXccoCAdoZqJZf49Bkd5rOdXLtvgwAAAABJRU5ErkJggg%3D%3D" /><span id="alt_lock" style="display: none; visibility: hidden;">&nbsp;<strong>[Lock]</strong>&nbsp;</span></a></div>
<div id="menu_print" style="cursor: pointer; display: inline; visibility: visible;"><a accesskey="p" id="woas_print_hl" title="Print" onclick="page_print()"><img id="img_print" style="display: inline; visibility: visible;" alt="Print" src="%2F%2F%2F%2Ff39%2Bfn5%2B%2Fv7w37xZMAAAABdFJOUwBA5thmAAABKUlEQVR42n2S2a6DIBRFZRKhBRkPU9X%2B%2F1de1A7el64HcsLKDmTDMPzCcnyB1vc%2BTJgSxgg9IMK8hRfLWsDVZWddvPwIBRkzrHKrWqeLsDMHz1hkMq3P5zWRGzeICIvysl4FCRRv69ZEzOH5%2BIoHB1OXddssZWjZE%2Bd986xiTqnqYunIdVnsPN3LMLTJGm%2BaLi0RhEjVXQRFhsFNGjNmitbegIJHerCpZrqLxu6BiGwyRGEIply1U7iC5BhtABKbxA3A6VdCp2gMz0qIWASr%2FbRTWNApuRhKyrduUHVBHWIMuleUUl%2FyLThVXDyFjfDGKUUUxI8IX7Cx4F9i9CF%2BCBCi9bvQs7F2%2FIelE%2BpdoUlIeduR8hikuKujRYRJrxXtj94HNhJOf%2F2cP%2B6HGtUMDq8TAAAAAElFTkSuQmCC" /><span id="alt_print" style="visibility: hidden; display: none;">&nbsp;<strong>[Print]</strong>&nbsp;</span></a></div>
<div id="menu_setkey" style="display: inline; cursor: pointer; visibility: visible;"><a title="Set password" onclick="set_key()"><img id="img_setkey" style="display: inline; visibility: visible;" alt="Set Key" src="%2FwD%2FoL2nkwAAAAlwSFlzAAAu6AAALugBK4TfhAAAA2ZJREFUSMe1ls1rXGUUxn%2FvnTsfma80JmkzWpvaVsii0lqx1VYpbWrRSYsiLbhRiqvOwoXSpSD%2BAW5cOCKIFtSFIoLWEaolIFKJMRQrRMU2HRXDtNNkviczc%2B%2B8r4ueGW%2FbaZoscuHlwuFynnOe9zzPucoYw1o%2BFmv82KuqJpVRgPKEjE4nl6VArYQiK5XxA0E5toBowAWaQFOnk%2B6qAaxUxgIiQAwIAyEBsATAARpADagA9Vs7uiOAlcrYQD%2BwDogLUB%2Fg9wC0gCWgCpSAIlDW6aReFkAqHwAGgXsEqNNFQADaQk9dqi8Ci8ACUOp00vOSJ3Z%2BsCsSLDxZrg%2BFfpo7nF2sjfgEJCL34PPwX%2FHEjMRbAnxzByc%2F3xeP2v9%2BEg5WJhQ3unTcYGv6yuEz52Zf%2BFWo6vN0UAfKUvl1IA9cA64C13U6qbsdjL15ynrukb%2B%2FDNrV%2FQ0nPJ%2BvbDwPrB%2Fpz%2B57%2FMEzzxfrw9GZ7HgeiEq1jnDvl8q9F96hstEFeGr72SNBu7p%2FqRWbPf3DGy%2FnK4k4kHh4dHJuYuf7J%2FZs%2FWbvTPbgeVD9krQJFCR5UxL3yaQFbwMI2pVxgHz1vnfzlURTkgQu%2FHVg7rFtmcJQdH7gtadThwyqKzSFMYBRSt4YgzJGgak2Rl%2BC5Ge2Z2AVQFv7tAipc3rYiVLcSE7Ablh%2Bn%2BNVN27bbmuDslIZ1QUoLW34IxIosSH%2Bz4shf32q4YQ1oHds%2Bn7bYDQ3sFAdqb1z7q1fgCGhoQbkj%2B9%2Be9NYYmqzMRYoUGgWavd%2B%2Bt7k69%2FqdNJ0AWYu7z69bnvu1XCgvCc1fuqjXPGBadvXun%2FjwJ9PgOHHS0cvyMRozx2UlNIuwOz83u8s5ba3DF886LZDLRnXm8f0xMcHRgcj2a%2BioeJDnZjjBp2pueTZyd%2BOXRJVRzxTVBtL%2FBwb6b8SyJU3X%2Fx9%2FtFpICfnqk4nm7cpOfbKh%2F5DO754NmRXd5WWhtTU5Weyhdp6vySP9dBBRabJq4NrwKJOJ%2FWdrCICDAvfg2IbcY%2BSvVbR8aGC2EReRNZYbh%2FUxVs6E%2BSKqS3nRSVRdFHid3VTSyjpUBOV6fF7AByPm5Ylec1r2XfbB0qSRlewD6pAa8X7oEc3ATm3brRWr8T%2FL1VjVn3Uya%2FVir9d69%2BW%2FwCh5sidoCxDaQAAAABJRU5ErkJggg%3D%3D" /><span id="alt_setkey" style="display: none; visibility: hidden;">&nbsp;<strong>[Set Key]</strong>&nbsp;</span></a></div>
<div id="menu_help" style="display: inline; cursor: pointer; visibility: visible;"><a accesskey="h" title="Help" id="woas_help_hl" onclick="woas.ui.help()"><img id="img_help" style="display: inline; visibility: visible;" alt="Help" src="%2FwD%2FoL2nkwAAAAlwSFlzAAAN1wAADdcBQiibeAAAAAd0SU1FB9oDCxIoGlBNSPYAAAcJSURBVEjHfZZrUJXHGcf%2Fu%2B%2FtvO%2B5QCwckItcFAMSg8WmhFiqUYuXRG3N5GLajmOa0dZG05HRzrRe%2BqHTzDTTRjL2g9iONBrTqo3BNMqkBR1BCKERKgpChHO4eTCcHM7hvHDOeS%2B7%2FVBgrNN2Z555Zndn%2Fs%2FuPvt7dgn%2BSxNFUcjKyqJ%2Bv988evSoPDY2liTLsirLskAIQTwetxOJRCwlJSVy4MABA%2F%2BnkYf66sWLF%2Fe4XK6vJkwzcf369SFJEFILCwsr3W53HqWUEEJgWRaPRCJDfX199SYwtGnDhmRKiNLU1NRRVVVV%2B78CpLe0tHx6p6fnoynbbjECYzWrV6505JY8Dk3TIEkSCCHgnINzDtM0oU9NYeyTT%2FFhW6tFPO43ChcVLAuFQnl79%2B59Stf1KAAIs%2BotLS3Xr169WhsKBhvyIvqpHQmipT22BOqifC5QShhjc%2BKUUgiCAFVR%2BLybPaTszgAdNhPLGztuHCwrL48XFBQcbmho%2BP1cgJqamo0TodAT94dHzq4j8odrVY9Kih%2FlTBCInZZCEpYFwzCQSCRgmiZs2wbnHNCnCO%2FqBnU4eMH9oJIkSS%2Be7fjsrc1btjxx7969YH9%2Ff58IAMtLS5d%2B3Nh4u9ih%2FflJ1SOjuAimQyFT%2FiFMj4ygLdmJP9TUoL29HZFIBNnZ2dj92mt4wT0PauA%2BklJSiZyTg%2BV9n9NRl6f2SnPTe7m5ucsA%2FFUEgIiuj9u6fmQbcaj2wlxuuDQS7h%2FAvabr%2BKL7Dp7%2FrPk%2FboLP58P%2Bqir4svOxu7wCZGEcj6R4IXtT%2Bab%2BAc%2Bvuf1KRNf3A4AIAOcuvO%2FYvW6jzCHAlCWifzGO4eZW%2BG93IxgO8yWpXrJ1104sWLCAc875hbo6Wn%2FpEs4FRrB1YAAyY1AZoGRnEvaNcqw1Y2LtX84TABBPnjwp%2Bny%2BgszyMgEeD6dT0yT6fh18HR0YiUxwz%2BNL8Vz2KiMSjb7Q2dnZTinlaenpZQAuhLmNyPQ0j%2FgGiXfrZmjfeRaKIPD80VGS3nRtUVVVlSR2d3cnlZSUVGqqCg4QJovQnqnEo%2Fk5ME6fIb0iNa6NDmc11V0cf%2BCUegAgLdXL8nZ8jyatqgApLoItiqCEEJfTifz8%2FGe6urp%2BQRVFUZOTk%2FMlSQLnHLZlw5iOQfGmIv2l5xFzadsfEhcAvA3AzshZcIitXQUxPQ3WdAyccxBC4HA44Ha7F1iWpVBCiEgpdRDyb%2BYYY2CMgds2wsEgmGE2PUT7MQCVAF5Zu2ZN7UQwyAnn4LPkEgJKKSilVJIkSh%2BuHXRmiBACURQhiuKDtO8H8EMAbwF4Z0Zobn52kbNAMsZAbdu2TNOMMcbmCBVFEYIkIT0jA5yQygcC%2FHjGvwkANuflWTk5oIoMQRDmSolhGLAsizHGGI3H49OhUOiOYRizlRSyUwMb8EOru4xlKd4TJd%2BsWDIjnD3jx9KKCrPLFxb8aV5zG8SrLZDcLgiCANu2EYvFEAqF7pqmGaNFRUXhW7du%2FS2q6wAhXKAUSZ23oR38JWIXL%2FOV3nRy%2BMVtN392%2BPBOABQADh458v3anx%2FyrStdLkSPneDJvzkGcf8RmMMjMCYn%2BUQ4jN7e3o%2FGx8cjBABe37dv95aVq6q%2FLjtEUVagLF6E%2BLETuN9wBcHpaT5vz05ib1iLseEREEKQlZsD540uTB76FfeqKpHmp4E9twlTPj%2FCg4O8LyMNJ%2F13f3L%2BnVNviwDw8raX%2BKUP6hIFnw%2BJjrx8LubmEGXndsyPJaA2N5PpkqWQqICKigoAwMjoKMyiAmRoTkIz0sG2PgvmVDF56zbX%2B%2FpIo70k7pIVAbNbNhOGJjmd776XpE3ovgESOXMWtkAhHtyHlIM%2FRXLJY3Bp2lymnZqGpOxs0DcOAT%2FaAZaeiokr1xDt7ycf52ZGXPl5tQldTwJAKQDp1KlT3UuLiyvq7%2FbtalLlaLizE8E3q3m8%2FQbItzciSdWQnJwMwzBgGAY8Hg80RYG8cgUMI4H7te%2FyL1s%2FwQ3vvMQHo8OvrygrK%2FMPDvYCcFEA8vHjx5sDgUDgB6%2B%2B%2Bt3fdXftOvOIM6QPDRH9ZhfMWJzP8iFJ0tzLZlkWYvE4120L0Z4ecjnLG60e9u%2F5bXX1xtOnTydaW1uvAJAJAA2AAkCrrq4%2Bt3jxYsffGxtb7ERi%2B5qiJc6iym8Rj9sNRVHmIDQMA7FYDOFwGB1tbazrH%2B3mlEP947qnny49f%2F48raurezkSiUwCMMhMHpQZE9avX7959erVX4vqOm9pa9M9mvaV0tLSJ%2BfPn79QURSVc454PB4PBAL%2Bjo6OVsu2v3xqxQpnbGpKqK%2Bv%2F2d7e3sdAAuACSBOHvoAyACkB0wAoGRmZnrcbrdKKRU554QxZuu6Hg8EApOMMQOAPSNqPSBuALD%2FBaO%2BPTDD5E81AAAAAElFTkSuQmCC" /><span id="alt_help" style="display: none; visibility: hidden;">&nbsp;<strong>[Help]</strong>&nbsp;</span></a></div>
<div id="menu_edit" style="display: inline; cursor: pointer; visibility: visible;"><a accesskey="e" id="woas_edit_hl" title="Edit" onclick="woas.ui.edit()"><img id="img_edit" style="display: inline; visibility: visible;" alt="Edit" src="" /><span id="alt_edit" style="display: none; visibility: hidden;">&nbsp;<strong>[Edit]</strong>&nbsp;</span></a></div>
<div id="menu_cancel" style="display: none; cursor: pointer; visibility: hidden;"><a title="Cancel" onclick="woas.ui.cancel()"><img id="img_cancel" style="display: inline; visibility: visible;" alt="Cancel" src="" /><span id="alt_cancel" style="display: none; visibility: hidden;">&nbsp;[Cancel]&nbsp;</span></a></div>
<div id="menu_save" style="display: none; cursor: pointer; visibility: hidden;"><a accesskey="s" id="woas_save_hl" title="Save" onclick="woas.save()"><img id="img_save" style="display: inline; visibility: visible;" alt="Save" src="" /><span id="alt_save" style="display: none; visibility: hidden;">&nbsp;<strong>[Save]</strong>&nbsp;</span></a></div>
</td></tr></tbody></table></div><p style="font-size: 20px;">&nbsp;</p>
<div id="i_woas_text_area" style="display: inline; visibility: visible;">
<div id="i_woas_menu_area" style="position: fixed;">
<div class="woas_wiki" id="woas_menu_area" ondblclick="menu_dblclick()"></div>
<div id="menu_edit_button" style="display: inline; visibility: visible;"><input class="woas_button woas_menu_button" value="Edit menu" title="Edit menu" onclick="edit_menu()" type="button" /></div>
<div class="woas_wiki" id="woas_ns_menu_area" ondblclick="woas.ui.ns_menu_dblclick()" style="display: none; visibility: hidden;"></div>
<div id="woas_ns_menu_edit_button" style="display: none; visibility: hidden;"><input class="woas_button woas_menu_button" value="Edit namespace menu" onclick="woas.ui.edit_ns_menu()" type="button" /></div>
</div>
<div style="visibility: visible;" class="woas_text_area" id="woas_wiki_area" ondblclick="page_dblclick()"></div>
<div style="display: none; visibility: hidden;" class="woas_page_mts" id="woas_mts"></div></div>
<div id="edit_area" style="display: none; visibility: hidden;">
<div id="woas_edit_page_title" style="display: block;">Page title: <input id="wiki_page_title" size="50" value="" />&nbsp;<a style="color: blue;" onclick="woas.wiki_buttons_display(d$('wiki_format_buttons').style.display != 'block')">Show/Hide wiki buttons</a>&nbsp;|&nbsp;<a style="color: blue;" onclick="woas.html_buttons_display(d$('html_format_buttons').style.display != 'block')">Show/Hide XHTML buttons</a></div>
<div id="wiki_format_buttons" style="display: block; visibility: visible;">
Wiki Code:
<input class="woas_editor_button woas_button" name="btn11" value="Wiki URL" title="Wiki page link" style="text-decoration: underline; width: 70px;" onclick="setWikiIUrl()" type="button" />
<input class="woas_editor_button woas_button" name="btn10" value="URL" title="External link" style="text-decoration: underline; width: 40px;" onclick="setWikiUrl()" type="button" />
<input class="woas_editor_button woas_button" name="btn7" value="=" title="Level 1 header" style="width: 40px;" onclick="TagThis('= ','')" type="button" />
<input class="woas_editor_button woas_button" name="btn8" value="==" title="Level 2 header" style="width: 40px;" onclick="TagThis('== ','')" type="button" />
<input class="woas_editor_button woas_button" name="btn9" value="Img" title="Include wiki image" style="width: 40px;" onclick="setWikiImage()" type="button" />
<input class="woas_editor_button woas_button" name="btn1" value=" B " title="Bold text" style="font-weight: bold; width: 30px;" onclick="TagThis('*', '*')" type="button" />
<input class="woas_editor_button woas_button" name="btn2" value=" i " title="Italic text" style="font-style: italic; width: 30px;" onclick="TagThis('/', '/')" type="button" />
<input class="woas_editor_button woas_button" name="btn3" value=" u " title="Underlined text" style="text-decoration: underline; width: 30px;" onclick="TagThis('_', '_')" type="button" />
<input class="woas_editor_button woas_button" name="btn4" value="{{{ }}}" title="Nowiki text" style="width: 70px;" onclick="TagThis('{{{\n', '\n}}}')" type="button" />
<input class="woas_editor_button woas_button" name="btn5" value="*" title="Bulleted list item" style="width: 40px;" onclick="TagThis('* ','')" type="button" />
<input class="woas_editor_button woas_button" name="btn6" value="#" title="Numbered list item" style="width: 40px;" onclick="TagThis('# ','')" type="button" />
<input class="woas_editor_button woas_button" name="btn7" value="@" title="Alphanumeric list item" style="width: 40px;" onclick="TagThis('@ ','')" type="button" />
<input class="woas_editor_button woas_button" name="btn8" value="Ruler" title="Ruler (horizontal line)" style="width: 46px;" onclick="woas.ui.editor._insert_ruler()" type="button" />
<input class="woas_editor_button woas_button" name="btn9" value="Tags" title="Wiki tag or tags" style="width: 43px;" onclick="setTag()" type="button" />
<a class="woas_world_link" onclick="woas.ui.tables_help()">Tables syntax</a>
</div>
<div id="html_format_buttons" style="display: block; visibility: visible;">XHTML Code:
<input class="woas_editor_button woas_button" name="b" title="Bold text" id="b" value="B" style="font-weight: bold;" onclick="FullTagThis('strong')" type="submit" />
<input class="woas_editor_button woas_button" name="i" title="Italic text" id="i" value="i" style="font-style: italic;" onclick="FullTagThis('em')" type="submit" />
<input class="woas_editor_button woas_button" name="u" title="Underlined text" id="u" value="u" style="text-decoration: underline;" onclick="FullTagThis('u')" type="submit" />
<input class="woas_editor_button woas_button" name="s" title="Strike-through text" id="s" value="S" style="text-decoration: overline;" onclick="FullTagThis('s')" type="submit" />
<input class="woas_editor_button woas_button" name="sup" title="Superscript text" id="sup" value="Sup" onclick="FullTagThis('sup')" type="submit" />
<input class="woas_editor_button woas_button" name="sub" title="Subscript text" id="sub" value="Sub" onclick="FullTagThis('sub')" type="submit" />
<input class="woas_editor_button woas_button" name="left" title="Align selection left" id="left" value="Left" onclick="DivTagThis('left')" type="submit" />
<input class="woas_editor_button woas_button" name="center" title="Align selection center" id="center" value="Center" onclick="DivTagThis('center')" type="submit" />
<input class="woas_editor_button woas_button" name="right" title="Align selection right" id="right" value="Right" onclick="DivTagThis('right')" type="submit" />
<input class="woas_editor_button woas_button" name="justify" title="Justify selection" id="justify" value="Justify" onclick="DivTagThis('justify')" type="submit" />
<input class="woas_editor_button woas_button" name="list" title="Unordered list" id="list" value="List" onclick="FullTagThis('ul')" type="submit" />
<input class="woas_editor_button woas_button" name="list_eq" title="Ordered list" id="list_eq" value="List=" onclick="FullTagThis('ol')" type="submit" />
<input class="woas_editor_button woas_button" name="li" id="li" title="List item" value="li [*]" onclick="FullTagThis('li')" type="submit" />
<input class="woas_editor_button woas_button" name="blockquote" title="Blockquote (indented text)" id="blockquote" value="Blockquote" onclick="FullTagThis('blockquote')" type="submit" />
<input class="woas_editor_button woas_button" name="img" id="img" title="Image link" value="Image" onclick="setHTMLImage()" type="submit" />
<input class="woas_editor_button woas_button" name="url" id="url" title="External link" value="Link" onclick="setHTMLUrl()" type="submit" />
</div>
<textarea style="width: 1885px; height: 812px;" id="woas_editor" rows="0" cols="0">&nbsp;</textarea> 
</div>
<div id="woas_footer"><table width="100%"><tbody><tr>
<td align="left" width="15%"><span style="visibility: hidden;" id="woas_debug_panel"><a title="Toggle debug display" onclick="d$.toggle('woas_debug_console')"><img style="display: inline; visibility: visible;" id="img_debug" alt="[Debug]" src="%2FL%2BobXKwtryrMXeWXKK2Ov%2Bk6zFy%2BT9pLzTvNXtSmJ6tc7njKW9nLDE9vn%2BvdLovtfwfZauutLpkKjA%2Bvz%2Fp8DZaYKbmLHKvNTrx%2BD4y%2BD18ff%2BwNjv%2F%2F%2F%2FN2g9%2FwAAAAF0Uk5TAEDm2GYAAAABYktHRACIBR1IAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH2gUXFDkoWkFbUwAAAINJREFUGNN9j9sOwiAQRNstF7lUEKRIq87%2F%2F6WkpQkmxnk72bOb2WH4HdR8sXNlQjd23hPlU8Kkny%2FDMPOMg72%2F3QMUiBL2%2FcqmsjIyNoVWxEih8YCRsEUss2pCZQZaeElM7Dc0EVTIJb1Xeyhac5nHdBX2LIKLVBuzXXs8hBD491yXD6ahCoFA3xZkAAAAAElFTkSuQmCC" /><!-- Needed for IE6 and IE7 --><span id="alt_debug" style="display: none; visibility: hidden;">[toggle
debug]</span></a></span></td>
<td align="center" width="70%"><span><a class="woas_link" title="About Wiki on a Stick" onclick="woas.ui.about()">About Wiki on a Stick v0.12.0</a></span></td>
<td align="right" width="15%"><a title="Go to top of page" onclick="javascript:woas.ui.top()"><img style="display: inline; visibility: visible;" id="img_top" alt="" src="" /><span id="alt_top" style="display: none; visibility: hidden;"></span></a></td></tr><tr>
<td colspan="3"><span id="woas_debug_console" style="visibility: hidden; display: none;"><div id="woas_debug_console_title">Debug console</div>
<textarea style="display: inline; visibility: visible;" id="woas_debug_log" rows="12" readonly="readonly" cols="60"></textarea><br /><input id="woas_debug_log_clear_button" title="Clear debug log" onclick="d$('woas_debug_log').value=''" value="Clear" class="woas_button" type="button" /></span></td></tr></tbody></table>
</div><script type="text/javascript">
//<![CDATA[
// this code needs to stay here for some Opera/Safari/Chrome restriction
// on DOM generation from extenal JavaScript
if (woas.use_java_io) {
	document.write("<"+"!-- "+__marker+"-TAIL-START -"+"->" +
					 "<applet style='position:absolute;left:-1px' name='TiddlySaver' code='TiddlySaver.class' archive='TiddlySaver.jar' width='1' height='1'></applet>"
					 + "<"+"!-- "+__marker+"-TAIL-END -"+"->");
}
//]]>
</script>
<div id="woas_custom_accesskeys">&nbsp;</div>


</body></html>